这是Method#to_proc中的错误吗? (Ruby 1.8.7)

时间:2011-01-18 07:59:33

标签: ruby ruby-1.8 destructuring proc-object

给出以下采用一个参数的方法:

def foo(arg); p arg; end

我可以用空数组调用它:

foo([])
# prints []

我还可以将其保存为Method对象,并使用空数组调用 ,结果相同:

method(:foo).call([])
# prints []

但是,如果我将Method对象转换为Proc并使用空数组调用 ,我会得到ArgumentError

method(:foo).to_proc.call([])
# ArgumentError: wrong number of arguments (0 for 1)
#   from (irb):4:in `foo'
#   from (irb):4:in `to_proc'
#   from (irb):10:in `call'

我预计它的行为与前两种情况相同。相反,它似乎表现得好像我写了foo(*[])。但是,如果我使用 -empty数组调用它, 的行为与我预期的方式相同:

method(:foo).to_proc.call([1])
# prints [1]

因此它会对参数进行解构,但前提是该参数恰好是一个空数组。只有我打电话给Method#to_proc

我对MethodProc的工作方式有何看法,或者这是一个错误?

我正在运行Ruby 1.8.7-p299。我在1.8.6-p399和1.8.7-head中观察到相同的行为。但是,我没有在1.9.1-p378中看到它:当使用空数组调用时,所有三个表单都打印[]

1 个答案:

答案 0 :(得分:13)

这几乎肯定是一个错误,

我怀疑发生这种情况的原因是Method#call有arity -1(期望C数组的参数),而Proc#call有arity -2(期望Ruby数组的参数)。

在eval.c中还有一个有用的评论,它在Proc#call的定义之上,可以进一步阐明这个问题:

/ * CHECKME:参数检查语义是否正确? * /

也许我们应该将其更改为FIXME:p