在Ruby 1.8(我的版本是1.8.7-72)中,这段代码:
foo = lambda do
for j in 1..2
return
end
end
foo.call
与LocalJumpError
:
test2.rb:3: unexpected return (LocalJumpError)
from test2.rb:2:in `each'
from test2.rb:2
from test2.rb:6:in `call'
from test2.rb:6
为什么这样做?但是,它似乎在我的Ruby 1.9版本上运行良好。
编辑:这不仅仅是在lambda内部返回;运行良好:
foo = lambda do
return
end
foo.call
答案 0 :(得分:8)
正在发生的事情是lambda中间的for语句被内部转换为块。在Ruby中,块内的返回语句的作用域是它们的封闭方法。请考虑以下事项:
def bar
foo = lambda do
for j in 1..2
return j
end
end
foo[]
end
p bar
运行bar
时,会返回1
,因为return
的范围限定为整个bar
方法。要从块返回,您需要使用next
或break
,两者都需要参数。考虑:
def bar
foo = lambda do
for j in 1..2
break j
end
end
foo[] + 1
end
p bar
此中断会从块返回,并阻止任何后续迭代。在这种情况下,调用bar
将返回2
,因为迭代器将返回1
,因此foo[] + 1
将返回2
。
如果所有这些都让人感到困惑,那么要认识到的主要内容是将块内部的返回范围限定为周围的方法,如果没有周围的方法,则会引发LocalJumpError
。
答案 1 :(得分:0)
你可以使用throw / catch
来转义循环和lambda的其余部分foo = lambda do
catch(:escape) do
for j in 1..2
throw :escape
end
# other code that won't get run
end # catch(:escape)
end # lambda
throw
还有一个可选的第二个参数,您可以使用它来返回值。