13

引数を 1 つ取る次のメソッドがあるとします。

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'

前の 2 つのケースと同じように動作することを期待していました。代わりに、私が書いたかのように動作しているようですfoo(*[])。ただし、空でない配列で呼び出すと、期待どおりに動作ます。

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

したがって、引数がたまたま空の配列である場合にのみ、引数を分解します。そして、私が電話した場合のみMethod#to_proc

Method方法や作業についての私の理解にギャップがありますかProc、それともバグですか?

Ruby 1.8.7-p299 を実行しています。1.8.6-p399 と 1.8.7-head で同じ動作が見られます。ただし、1.9.1-p378 には表示されません[]。空の配列で呼び出すと、3 つのフォームすべてが出力されます。

4

1 に答える 1

13

これはほぼ間違いなくバグです。

これが発生する理由は、Method#call のアリティが -1 (引数の C 配列が必要) であり、Proc#call のアリティが -2 (引数の Ruby 配列が必要) であるためだと思われます。

eval.c には Proc#call の定義の上にさらに役立つコメントがあり、この問題をさらに明らかにする可能性があります。

/* CHECKME: 引数チェックのセマンティクスは正しいですか? */

たぶん、それを FIXME に変更する必要があります:p

于 2011-01-18T18:16:55.287 に答える