为什么带有splat参数的Ruby procs/blocks的行为与方法和lambda不同?

Jor*_*dan 7 ruby lambda block splat proc

为什么Ruby(2.0)使用splat参数处理/块的行为与方法和lambda不同?

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
Run Code Online (Sandbox Code Playgroud)

以下是对此行为的确认,但没有解释:http: //makandracards.com/makandra/20641-careful-when-calling-a-ruby-block-with-an-array

Vic*_*roz 3

有两种类型的Proc对象:lambda以与普通方法相同的方式处理参数列表,以及proc使用“技巧”(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
Run Code Online (Sandbox Code Playgroud)