от
В Ruby 1.8, есть тонкие различия между proc и/лямда-с одной стороны, и
Proc.new
на других. Каковы эти различия? Можете ли вы дать рекомендации о том, как решить, какой выбрать? В Ruby 1.9, proc и Lambda-это другое. В чем же дело?

Ваш ответ

Отображаемое имя (по желанию):
Конфиденциальность: Ваш электронный адрес будет использоваться только для отправки уведомлений.
Анти-спам проверка:
Чтобы избежать проверки в будущем, пожалуйста войдите или зарегистрируйтесь.

15 Ответы

0 голосов
от
В Ruby 1.8, есть тонкие различия между proc и/лямда-с одной стороны, и
Proc.new
на других. Каковы эти различия? Можете ли вы дать рекомендации о том, как решить, какой выбрать? В Ruby 1.9, proc и Lambda-это другое. В чем же дело?
0 голосов
от
Еще одна важная, но тонкое различие между проками, созданные с
lambda
и процедур, созданных с
Proc.new
как они обрабатывают заявления
return
: В
lambda
-созданные труды, в
return
оператор возвращает только прок себе В
Proc.new
-созданные труды, заявление
return
немного более удивительно: он возвращает контроль не только прок, но и от метода, включающего прок! Вот
lambda
-создан
return
прок в действии. Он ведет себя так, что вы, вероятно, ожидаете:
def whowouldwin

  mylambda = lambda {return "Freddy"}
  mylambda.call

  # mylambda gets called and returns "Freddy", and execution
  # continues on the next line

  return "Jason"

end


whowouldwin
#=
0 голосов
от
Чтобы предоставить дальнейшие разъяснения: Джо говорит, что возвращение поведение
Proc.new
удивительно. Однако если учесть, что прок.новый ведет себя как блок, это не удивительно, потому что именно так ведут себя блоки. Ламбас с другой стороны вести себя как методы. Это фактически объясняет, почему прокся являются гибкими, когда дело доходит до арность (количество аргументов), а лямбды нет. Блоки не требуют, чтобы все их аргументы должны быть предоставлены, но методы (если предусмотрено по умолчанию). Обеспечивая лямда-умолчанию аргумент-это не вариант в Ruby 1.8, на сегодняшний день он поддерживается в Ruby 1.9 с альтернативный синтаксис лямбда (как отметил webmat):
concat = 

И (ОП) Мишель де Маре неверно о проками и лямбда ведет себя так же с арности в Ruby 1.9. Я проверил, что они все еще сохраняют поведение с 1,8, как указано выше.

break
заявления на самом деле не имеет смысла в любом прокся или лямбд. В прок, перерыва вернется вы из тез.Докл.новый, который уже завершен. И это не имеет никакого смысла, чтобы вырваться из лямбда-выражения, поскольку по сути это метод, и вы никогда не может нарушить верхнем уровне метода.
next
,
redo
, и
raise
ведут себя одинаково в обоих проков и лямбды. В то время как
retry
не допускается в любом и вызывает исключение. И, наконец, метод
proc
никогда не должны использоваться, поскольку оно не согласуется и с неожиданным поведением. В Ruby 1.8, он на самом деле возвращает лямбда-выражение! В Ruby 1.9 это было исправлено и возвращает Тез. Докл. Если вы хотите создать труды, придерживаться
Proc.new
. Для получения дополнительной информации, я настоятельно рекомендую О'Рейли язык программирования Ruby, который является моим источником для большинства этой информации.
0 голосов
от
Я нашел эту страницу, которая показывает, что разница между
Proc.new
и
lambda
являются. Согласно странице, единственное отличие заключается в том, что лямбда-выражение имеет строгое количество аргументов, которые он принимает, а
Proc.new
преобразует хватает аргументов
nil
. Вот пример сессии ИРБ, иллюстрирующий разницу: ирб(основной):001:0> Л = лямбда { |х, г| х г } => #
0 голосов
от
Учеб старше, но семантика возвращения крайне нелогичным для меня (по крайней мере, когда я учил язык), потому что: Если вы используете прок, вы, скорее всего, через какой-то функциональной парадигмы. Прок может вернуться из внешней области видимости (см. предыдущие ответы), который Гото в основном, и очень нефункциональными. Лямда-функционально безопаснее и легче рассуждать - я всегда использую его вместо proc.
0 голосов
от
Я не могу сказать про тонкие различия. Однако, я могу отметить, что Руби 1.9 теперь позволяет дополнительные параметры лямбда-выражения и блоки. Вот новый синтаксис для лямбд колоть под 1.9:
stabby = 

Руби 1.8 не было, что синтаксис. Не обычный способ объявления блоки/лямбды поддерживают дополнительные аргументы:

# under 1.8
l = lambda { |msg = 'inside the stabby lambda'|  puts msg }
SyntaxError: compile error
(irb):1: syntax error, unexpected '=', expecting tCOLON2 or '[' or '.'
l = lambda { |msg = 'inside the stabby lambda'|  puts msg }
Руби 1.9, однако, поддерживает необязательные аргументы даже со старым синтаксисом:
l = lambda { |msg = 'inside the regular lambda'|  puts msg }
#=
0 голосов
от
Короткий ответ: важно то, что
return
делает: лямбда возвращает из себя и возвращает прок из себя и функцию, которая его вызвала. Что менее ясно, почему вы хотите использовать каждый. лямда-это то, что мы ожидаем, что следует сделать в функциональном смысле программирования. Это в основном анонимный метод с текущей области видимости автоматически привязывается. Из двух, лямда-вы, вероятно, следует с помощью. Прок, с другой стороны, это очень полезно для реализации самого языка. Например, можно реализовать "если" заявления или "для" петли с ними. Любое возвращение найден в прок будет возвращать из метода, который называется, не только "если" заявление. Это как языки работают, как "если" заявления работу, так что я думаю, Руби использует этот под одеяло, и они просто выставили его, потому что он казался мощным. Вам бы только действительно это нужно, если вы создаете новые языковые конструкции, такие как петли, Если-нибудь конструкции и т. д.
0 голосов
от
Хороший способ, чтобы увидеть это, что лямбда-выражения выполняются в собственном объеме (как если бы это был вызов метода), в то время как процедур может рассматриваться как выполненные в соответствии с вызывающем методе, по крайней мере, это хороший способ решить, какой именно использовать в каждом конкретном случае.
0 голосов
от
Я не заметил каких-либо комментариев по третьей способ в вопрос, "прок", которое является устаревшим, но обрабатывается по-разному в 1.8 и 1.9. Вот довольно подробный пример, который делает его легко увидеть различия между тремя аналогичными призывами:
def meth1
  puts "method start"

  pr = lambda { return }
  pr.call

  puts "method end"  
end

def meth2
  puts "method start"

  pr = Proc.new { return }
  pr.call

  puts "method end"  
end

def meth3
  puts "method start"

  pr = proc { return }
  pr.call

  puts "method end"  
end

puts "Using lambda"
meth1
puts "
0 голосов
от
Замыкания в Ruby-это хорошее представление для того, как блоки, лямбды и прок работать в Ruby, Руби.
...