Только что столкнулся с похожей проблемой!
В любом случае, мои основные выводы:
Оператор splat работает для назначения массива предсказуемым образом.
Процедуры эффективно назначают аргументы для ввода (см. Заявление об отказе от ответственности ниже)
Это приводит к странному поведению, т.е. пример выше:
baz = proc do |ids, *args|
p ids
end
baz.call([1,2,3]) # => 1
Так что же происходит? [1,2,3]
передается в baz
, который затем присваивает массив своим аргументам
ids, *args = [1,2,3]
ids = 1
args = [2,3]
При запуске блок проверяет только ids
, то есть 1
. На самом деле, если вы вставите p args
в блок, вы обнаружите, что это действительно [2,3]
. Определенно не тот результат, который можно было бы ожидать от метода (или лямбды).
Отказ от ответственности: я не могу с уверенностью сказать, просто ли процедуры назначают свои аргументы для ввода под капотом. Но похоже, что это соответствует их поведению, когда не применяется правильное количество аргументов. На самом деле, если вы даете процедуре слишком много аргументов, она игнорирует лишние. Слишком мало, и это проходит в нулях. Точно так же, как присваивание переменных.
person
phil-ociraptor
schedule
12.06.2014
join...
только излишне усложняет его. Это не имеет отношения к вашему вопросу. Все, что вам нужно сделать, это сделатьp ids
в каждом блоке и прояснить, чем он отличается. - person sawa   schedule 30.05.2014proc
является стандартным библиотечным методом, аlambda
является специальным ключевым словом... - person Idan Arye   schedule 30.05.2014*args
делает арность необязательной, но знак все равно применяется. Я подозреваю, что это может быть ошибка. - person sawa   schedule 30.05.2014f = ->((x, *xs)) { ... }
, так что не-лямбда-блок, вероятно, может рассматриваться как лямбда-выражение с неявными скобками. - person Victor Moroz   schedule 30.05.2014lambda
иproc
оба метода:[3] pry(main)> method :lambda => #<Method: Object(Kernel)#lambda>
Я проверил это на Ruby 1.9.3 и 2.0.0. - person Darek Nędza   schedule 30.05.2014lambda
также является ключевым словом. Когда вы используете его напрямую, возврат из тела лямбды не возвращается из включающего метода, но когда вы используете его черезmethod(:lambda).call
, он ведет себя как обычный метод с блоком, а возврат из блока возвращает из вмещающего метода. - person Idan Arye   schedule 30.05.2014lambda
/->
возвращается из блока, НОproc
/Proc.new
поднимаетLocalJumpError: unexpected return
. Это действительно странно, потому что в упомянутых версияхlambda
работает так, как я описал. Это может быть ошибка 2.1.*. - person Darek Nędza   schedule 30.05.2014