4

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

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

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

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

4

3 回答 3

9

这是因为 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

查看使用 Ruby进行解构以获取更多信息。

于 2012-12-18T05:50:26.837 回答
3

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

[[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]
于 2012-12-18T05:38:03.280 回答
1

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]
于 2012-12-18T05:34:23.073 回答