Я пробовал читать о procs и лямбда, но я должен продолжать перечитывать определение.
Может кто-нибудь объяснить это мне таким образом, что это понятно и запоминаемо?
Я пробовал читать о procs и лямбда, но я должен продолжать перечитывать определение.
Может кто-нибудь объяснить это мне таким образом, что это понятно и запоминаемо?
Несколько ресурсов:
Также есть целая глава в Read Ruby 1.9 book
Отредактировано: после прочтения других хороших ответов здесь я предлагаю следующую дистилляцию, которая может спасти вас от повторного чтения:
(l)ambda -
(L)ocal return
(L)ooks at the arguments
(p)roc -
(P)ops you out of the method when it returns.
(P)ermits different arguments
Эйнштейн сказал: "... делайте все как можно проще, но не проще". Если бы у него было переполнение стека, он бы указал вам здесь:
В чем отличия между proc и лямбдой?
или здесь:
В чем разница между proc и лямбдой в Ruby?
hth -
Перри
То, как я думаю о них, состоит в том, что лямбда ведет себя скорее как функция, а Proc или block ведет себя скорее как структура управления.
Я думаю, что лучший способ понять, почему эти два существуют и какова разница, - это понять, как каждый используется. Возьмите этот код, например:
def find (elem)
@array.each { |item| return item if item == elem }
return false
end
Для всех, знакомых с Ruby, очевидно, что здесь происходит, но спросите себя, с чего вы возвращаетесь, когда вызывается return. То, что вы ожидаете, и что происходит, заключается в том, что сам метод возвращается. Несмотря на то, что мы находимся внутри блока кода, это возвращает метод, а не только блок. Так ведет себя Proc, и это позволяет нам использовать цикл .each и возвращать его, как и в эквивалентном цикле for.
С другой стороны, лямбда - это как функции. Если вы вернетесь из лямбда, он выходит только из лямбды.
def find (elem)
l = lambda { |item| return item if item == elem }
@array.each(&l)
return false
end
Здесь метод всегда будет возвращать false из-за того, что окончательная строка не обходится вызовом return в лямбда. Lambdas являются функциями и возвращаются от себя, тогда как Procs возвращаются из прилагаемого метода.
Итак, Procs и блоки и возвращаются из метода, использующего их (например, цикл будет), в то время как lambdas (например, методы) возвращаются от себя.
Proc ведут себя как блоки. Lambdas ведут себя как методы.
т.е. return внутри a Proc ведет себя как return внутри блока, а привязка аргументов для Proc работает так же, как привязка аргументов для блоков. return внутри lambda работает как return внутри метода и привязка аргумента для lambdas работает так же, как привязка аргумента для методов.
Обратите внимание, что lambdas Proc s, то есть они являются экземплярами класса Proc. Разница между ними заключается в том, является ли Proc#lambda? true или false.
Обратите также внимание на то, что в старых версиях Ruby Kernel#proc создан лямбда, а не Proc, что было совершенно запутанно. Это было исправлено в современных версиях Ruby, где Kernel#proc теперь эквивалентно Proc.new и, таким образом, создает Proc.
Kernel#lambda и синтаксис лямбда-литерала (->(x, y) { x + y }) всегда создают лямбда, Proc.new всегда создает Proc и Kernel#proc в зависимости от версии Ruby.
В Proc:
В лямбда:
Как и Jorg W Mittag, Procs ведут себя как блоки, а lambdas ведут себя как методы.
То, как я запоминаю, это "proc", рифмуется с "блоком".