Вызов / применение лямбда против вызова функции - синтаксис в Ruby отличается. Зачем? - PullRequest
30 голосов
/ 14 июня 2011

Я немного новичок в Ruby и все еще пытаюсь понять некоторые принципы языкового дизайна.Если я правильно понял, вызов лямбда-выражения в Ruby должен быть с квадратными скобками, в то время как «обычный» вызов функции - с «обычными» / круглыми скобками.

Есть ли особая причина, по которой синтаксис отличается?Или, другими словами, (почему) вызывающий должен знать, вызывают ли они функцию или применяют лямбда-выражение?

Ответы [ 3 ]

31 голосов
/ 14 июня 2011

Обычные вызовы методов Ruby используют () не фигурные скобки для блоков. Если вам не нравится [] для вызова лямбды, вы всегда можете использовать метод call.

Пример:

>> by_two = lambda { |x| x * 2 } #=> #<Proc:0x0000000101304588@(irb):1>
>> by_two[5] #=> 10
>> by_two.call(5) #=> 10

Редактировать

В более новой версии Ruby также:

>> by_two.(5) #=> 10

Что касается того, почему вы не можете просто сделать by_two(5), когда Ruby видит голое слово, он сначала пытается разрешить его как локальную переменную, и если это не удается как метод.

28 голосов
/ 14 июня 2011

Поскольку в Ruby методы не являются лямбда-выражениями (как, например, в JavaScript).

Методы всегда принадлежат объектам, могут быть унаследованы (путем подклассификации или смешивания), могут быть перезаписаны вСобственный класс объекта и может быть дан блок (который является лямбда).У них есть своя область видимости для переменных.Пример определения метода:

a = :some_variable
def some_method
  # do something, but not possible to access local variable a
end

# call with:
some_method

Однако лямбда-выражения / процедуры являются простыми замыканиями, возможно, хранятся в переменной - ничего больше:

a = :some_variable
some_lambda = lambda{
  # do something, access local variable a if you want to
}

# call with:
some_lambda[]

Ruby сочетает, например, оба подхода с мощным синтаксисомПроходные блоки:

def some_method_with_block(a)
  # do something, call given block (which is a lambda) with:
  yield(a) ? 42 : 21
end

# example call:
some_method_with_block(1) do |x|
  x.odd?
end #=> 42
11 голосов
/ 15 июня 2011

Если вам нужны скобки, вы можете сделать

by_two = lambda { |x| x * 2 }
by_two.(5) # => 10

Обратите внимание на . между by_two и (5).

...