为什么Ruby(2.0)使用splat参数处理/块的行为与方法和lambdas不同?
def foo (ids, *args)
p ids
end
foo([1,2,3]) # => [1, 2, 3]
bar = lambda do |ids, *args|
p ids
end
bar.call([1,2,3]) # => [1, 2, 3]
baz = proc do |ids, *args|
p ids
end
baz.call([1,2,3]) # => 1
def qux (ids, *args)
yield ids, *args
end
qux([1,2,3]) { |ids, *args| p ids } # => 1
这是对此行为的确认,但没有说明: http://makandracards.com/makandra/20641-careful-when-calling-a-ruby-block-with-an-array
答案 0 :(得分:1)
有两种类型的Proc
对象:lambda
以与普通方法相同的方式处理参数列表,proc
使用" tricks" (Proc#lambda?)。 proc
如果数组是唯一的参数,则会展开数组,忽略额外的参数,将nil
分配给缺失的数组。您可以使用解构来部分模仿proc
lambda
行为:
->((x, y)) { [x, y] }[1] #=> [1, nil]
->((x, y)) { [x, y] }[[1, 2]] #=> [1, 2]
->((x, y)) { [x, y] }[[1, 2, 3]] #=> [1, 2]
->((x, y)) { [x, y] }[1, 2] #=> ArgumentError
答案 1 :(得分:0)
刚遇到类似的问题!
无论如何,我的主要内容是:
splat运算符以可预测的方式用于数组赋值
Procs有效地为输入分配参数(参见下面的免责声明)
这会导致奇怪的行为,即上面的例子:
baz = proc do |ids, *args|
p ids
end
baz.call([1,2,3]) # => 1
那么发生了什么? [1,2,3]
传递给baz
,然后将数组分配给其参数
ids, *args = [1,2,3]
ids = 1
args = [2,3]
运行时,该块只会检查ids
,1
。实际上,如果您将p args
插入块中,您会发现它确实是[2,3]
。当然不是人们对方法(或lambda)的期望。
免责声明:我无法确定Procs是否只是将其参数分配给引擎下的输入。但它似乎与他们不强制执行正确数量的参数的行为相匹配。事实上,如果你给Proc太多的论点,它会忽略额外的东西。太少了,它通过了nils。完全像变量赋值。