Сообщение от x-yuri
|
а можно увидеть, как эта функция на Ruby выглядела бы?
|
Ну, для начала общий пример (из Википедии):
# ruby
def foo
f = Proc.new { return "return from foo from inside proc" }
f.call # control leaves foo here
return "return from foo"
end
def bar
f = lambda { return "return from lambda" }
f.call # control does not leave bar here
return "return from bar"
end
puts foo # prints "return from foo from inside proc"
puts bar # prints "return from bar"
Замыкания, порождаемые Proc.new - при return-e могут завершать контекст, в котором были порождены.
Замыкания, порождаемые функцией lambda - не могут.
Касаемо массива, метода .each и фунарга - я проверил, в версии 1.8.6 - и lambda, почему-то, завершает порождаемый контекст. В версии 1.9.1. это исправлено:
def test1
fn = lambda {|x| return x}
[1, 2, 3].each(&fn) # процедура передаётся с амперсандом
return nil
end
def test2
fn = Proc.new {|x| return x}
[1, 2, 3].each &fn # скобки вызова - опциональны
return nil
end
puts test1 # 1 - в 1.8.6, nil (правильно) - в 1.9.1
puts test2 # 1 - правильно
Есть ещё третий способ создать замыкание в Ruby - это блок кода (который можно преобразовать в процедуру). Различные методы (типа .each) как раз и используются с этими блоками кода.
def test3
[1, 2, 3].each {|x| return x} # сразу описываем блок кода
nil # слово return - тоже опциональное
end
puts test3 # 1 - при использовании блока, тоже выход из порождающего контекста