Это ошибка в методе # to_proc? (Ruby 1.8.7) - PullRequest
13 голосов
/ 18 января 2011

Учитывая следующий метод, который принимает один аргумент:

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(*[]).Однако если я вызову его с массивом non -empty, он будет вести себя так, как я ожидал:

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

Таким образом, он разрушает аргумент, но толькоесли аргумент оказывается пустым массивом.И только если я позвоню Method#to_proc.

Есть ли пробел в моем понимании того, как Method или Proc работает, или это ошибка?

Я использую Ruby1.8.7-P299.Я наблюдаю такое же поведение в 1.8.6-p399 и 1.8.7-head.Однако я не вижу этого в 1.9.1-p378: там все три формы печатают [] при вызове с пустым массивом.

1 Ответ

13 голосов
/ 18 января 2011

Это почти наверняка ошибка,

Я подозреваю, что причина этого заключается в том, что вызов метода # имеет арность -1 (ожидается массив аргументов C), а вызов Proc # имеет арность -2 (Ожидается массив аргументов Ruby).

В eval.c есть еще один полезный комментарий над определением вызова Proc #, который может пролить дополнительный свет на проблему:

/ * CHECKME: areсемантика проверки аргументов верна?* /

Может быть, мы должны изменить это на FIXME: p

...