Вызов/применение вызова lambda vs. function - синтаксис в Ruby отличается. Зачем?
Я новичок в Ruby и все еще пытаюсь понять некоторые принципы языкового дизайна. Если у меня все получится, вызов выражения лямбда в Ruby должен быть с квадратными скобками, а "обычный" вызов функции - с "регулярными" /круглыми фигурными скобками.
Есть ли особая причина, по которой синтаксис отличается? Или, другими словами, (почему), должен ли вызывающий абонент знать, вызывают ли они функцию или применяют лямбда-выражение?
Ответы
Ответ 1
Потому что в Ruby методы не lambdas (например, в JavaScript).
Методы всегда относятся к объектам, могут быть наследованы (путем подклассификации или mixins), могут быть перезаписаны в объекте eigenclass и могут быть заданы блок (который является лямбдой). У них есть свои возможности для переменных. Пример определения метода:
a = :some_variable
def some_method
# do something, but not possible to access local variable a
end
# call with:
some_method
Однако lambdas/procs - это простые замыкания, возможно, хранятся в переменной - ничего больше:
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
Ответ 2
В обычных вызовах Ruby используется ()
не фигурные скобки, которые для блоков. Если вам не нравится []
для вызова лямбда, вы всегда можете использовать метод call
.
Пример:
>> by_two = lambda { |x| x * 2 } #=> #<Proc:[email protected](irb):1>
>> by_two[5] #=> 10
>> by_two.call(5) #=> 10
Edit
В новой версии Ruby также:
>> by_two.(5) #=> 10
Относительно того, почему вы не можете просто сделать by_two(5)
, когда Ruby видит одно открытое слово, он сначала пытается разрешить его как локальную переменную, и если это не удается как метод.
Ответ 3
Если вы хотите скобки, вы можете сделать
by_two = lambda { |x| x * 2 }
by_two.(5) # => 10
Обратите внимание на .
между by_two
и (5)
.