Рубин лямбда аргументы - PullRequest
       7

Рубин лямбда аргументы

21 голосов
/ 09 февраля 2010

Этот код работает должным образом (ничего не делает, даже не выдает предупреждение / ошибки):

l = lambda {|i|}
l.call(1)

Этот код выдает предупреждение (предупреждение: множественные значения для параметра блока (0 для 1)):

l = lambda {|i|}
l.call

И этот код завершается с ошибкой (ArgumentError: неверное количество аргументов (0 для 2)):

l = lambda {|i, y|}
l.call

Я думал, что лямбда требует передачи всех аргументов.

И из второго примера я вижу, что это не так. Почему это работает, когда дается только один аргумент, и работает как ожидалось (не с ошибкой) с более чем одним аргументом?

PS: ruby ​​1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]

ОБНОВЛЕНИЕ: я проверил эти образцы на ruby ​​1.9.1p376. И это работает как положено - второй пример также выдает ошибку. Похоже, это особенность версии 1.8 (или <= 1.8) </p>

Ответы [ 3 ]

14 голосов
/ 09 февраля 2010

Лямбды такие странные, их поведение отличается, когда у вас меньше двух аргументов. Проверьте эту статью для получения дополнительной информации.

13 голосов
/ 09 февраля 2010

Этот скрипт научит вас всему, что вам нужно знать о замыканиях в Ruby.

# So, what's the final verdict on those 7 closure-like entities?          
#
#                                                     "return" returns from closure
#                                    True closure?    or declaring context...?         Arity check?
#                                    ---------------  -----------------------------    -------------------
# 1. block (called with yield)       N                declaring                        no
# 2. block (&b => f(&b) => yield)    N                declaring                        no
# 3. block (&b => b.call)            Y except return  declaring                        warn on too few
# 4. Proc.new                        Y except return  declaring                        warn on too few
# 5. proc                                    <<< alias for lambda in 1.8, Proc.new in 1.9 >>>
# 6. lambda                          Y                closure                          yes, except arity 1
# 7. method                          Y                closure                          yes
6 голосов
/ 18 мая 2016

Когда лямбда-выражение ожидает аргументы, а мы их не предоставляем или неверное количество аргументов выдается, возникает исключение.

l = lambda { |name| puts "Today we will practice #{name} meditation." }
l.call
ArgumentError: wrong number of arguments (given 0, expected 1)

Мы можем использовать метод arity для определения количества ожидаемых аргументов:

l.arity  # Output: => 1

Как и методы, лямбда-выражения принимают все следующие типы параметров / аргументов:

  • Позиционные параметры (обязательные и необязательные)
  • Параметр одиночного знака (*);
  • Параметры ключевых слов (обязательные и необязательные);
  • Параметр двойного сплата (**);
  • Явный параметр блока с префиксом амперсанда (&).

Следующие примеры иллюстрируют синтаксис лямбды, которая принимает аргументы нескольких типов.

# Stabby syntax
l = -> (cushion, meditation="kinhin", *room_items, time:, posture: "kekkafuza", **periods, &p) do
  p.call
end

# Regular syntax
l = lambda do |cushion, meditation="kinhin", *room_items, time:, posture:     "kekkafuza", **periods, &p|
  p.call
end

l.call("zafu", "zazen", "zabuton", "incense", time: 40, period1: "morning", period2: "afternoon" ) { puts "Hello from inside the block, which is now a proc." }

Output:
Hello from inside the block, which is now a proc.

Лямбды обрабатывают аргументы так же, как и методы. В этом посте о методах есть подробное объяснение всех вышеперечисленных типов параметров / аргументов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...