【问题标题】:Number of arguments in a ruby blockruby 块中的参数数量
【发布时间】:2012-12-18 05:27:57
【问题描述】:

我是 Ruby 新手,但不熟悉允许 lambda 的语言,例如 groovy。所以我看到了这个例子:

myArray.product(otherArray).reject{|i,j| i > j}

在一个 ruby​​ 代码块中,我之前没有看到这个块接受 2 个参数,但是当我去查看 documentation 时,我只能看到说明它需要 1 个参数的文档。我查看了 enumerable 类的相同内容,但该文档也仅显示 1 个参数。

我知道它有效,我想我希望有一种更简单的方法来确定它需要多少个参数,而不是猜测和测试方法。如何判断一个块在 Ruby 中接受多少个参数?

【问题讨论】:

  • 你为什么不接受 Brandon Tilley 的回答?
  • 点击错误,没看到。他的答案正是我想要的。

标签: ruby lambda


【解决方案1】:

这是可行的,因为 Ruby 支持解构。

解构允许您将一组变量绑定到一组相应的值,您通常可以将一个值绑定到单个变量。

这允许以下情况成立:

arr = [1, 2]
x = arr
x == [1, 2] # true

y, z = arr
y == 1 # true
z == 2 # true

您可以从以下代码中看到,块参数中的解构并不是采用块的内置方法所独有的:

def my_method(arr)
  yield arr
end

my_method([1, 2, 3]) {|x| puts x.inspect }
# => [1, 2, 3]
my_method([1, 2, 3]) {|x, y, z| puts x.inspect }
# => 1

查看Destructuring with Ruby了解更多信息。

【讨论】:

  • 正是我在看的内容,解释了我不理解的内容,谢谢。
【解决方案2】:

您可以根据数组的结构对块参数进行一些有趣的重组:

[[1, 2], [3, 4], [5, 6], [7, 8]].reject {|x,y| y == 8 }
#=> [[1, 2], [3, 4], [5, 6]]

您可以将它们分组在括号中:

[ [[1,2],3], [[1,3],6] ].select {|(x,y),z| x == 1 && z == 3 }
#=> [ [[1,2],3] ]

您还可以将 splat 运算符用于各种事情,例如处理可变长度子数组:

[[:a,:b,2,3,4,5,6], [:c,:d,7,8,9]].each {|x,y,*numbers| puts numbers.inspect }
#=> [2,3,4,5,6]
#=> [7,8,9]

【讨论】:

  • 虽然这展示了一些简洁的示例,但我的问题更多地指向了如何能够判断什么作为块的参数起作用,即当reject 方法获取块时,你怎么能告诉它传递了什么参数。
【解决方案3】:

Ruby 在解释参数方面很灵活;这是一个类似的例子,有一个,然后是两个参数:

[1, 3].product([2, 4]).reject {|a| a.first > a.last }
=> [[1, 2], [1, 4], [3, 4]] 
[1, 3].product([2, 4]).reject {|a,b| a > b }
=> [[1, 2], [1, 4], [3, 4]] 

这里的经验法则是,您可以将参数视为复合对象或集合中的单个元素。例如,

[1, 2, 3].tap {|a,b,c| puts [a,b,c].inspect }
[1, 2, 3]
... 
[1, 2, 3].tap {|a,b| puts [a,b].inspect }
[1, 2]
... 
[1, 2, 3].tap {|a| puts a.inspect }
[1, 2, 3]

【讨论】:

  • 我知道它有效,我想我希望有一种更简单的方法来确定它需要多少参数而不是猜测和测试方法。
  • 大多数都相当灵活,但通常默认使用一个参数。如有疑问,请查看文档。有些通常需要两个,例如哈希枚举,当与单个块参数一起使用时会产生一个二元素数组(例如,{:a => 1, :b => 2}.each {|x| ... } 使用 [:a,1][:b,2])。
  • 当我链接时,我给出的示例 Array.reject 的文档仅显示一个参数,而代码显示 1 或 2。
  • @Nicholas: #reject 只是接受一个块参数。与此处相关的是块的行为,而不是#reject。它是解包参数的块,或者不是,视情况而定。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-02-01
  • 2020-10-28
  • 2015-03-15
  • 1970-01-01
  • 1970-01-01
  • 2021-12-19
  • 1970-01-01
相关资源
最近更新 更多