为什么在Ruby中屈服于lambda splat数组参数?

Ste*_*fan 9 ruby lambda yield

在Ruby中,lambda使用错误数量的参数调用a会导致ArgumentError:

l = lambda { |a, b| p a: a, b: b }
l.call(1, 2) 
# {:a=>1, :b=>2}

l.call(1)
# ArgumentError: wrong number of arguments (given 1, expected 2)
Run Code Online (Sandbox Code Playgroud)

传递数组也不起作用:(因为数组只是一个对象,对吧?)

l.call([3, 4])
# ArgumentError: wrong number of arguments (given 1, expected 2)
Run Code Online (Sandbox Code Playgroud)

除非我使用splat(*)将数组转换为参数列表,否则我没有.

但是 ......如果我通过隐式调用lambda yield,会发生意外情况:

def yield_to
  yield(1, 2)
  yield([3, 4])
end

yield_to(&l)
# {:a=>1, :b=>2}
# {:a=>3, :b=>4}   <- array as argument list!?
Run Code Online (Sandbox Code Playgroud)

更令人困惑的是,lambda派生的via Method#to_proc会按预期工作:

def m(a, b)
  p a: a, b: b
end

yield_to(&method(:m))
# {:a=>1, :b=>2}
# ArgumentError: wrong number of arguments (given 1, expected 2)
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

Ste*_*fan 4

我在这里回答我自己的问题,因为这是一个已知的错误:

https://bugs.ruby-lang.org/issues/12705

它已在 Ruby 2.4.1 中修复(感谢@ndn)