在 Ruby 1.8 中,返回 lambda 内的 for 循环会崩溃
在 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
In Ruby 1.8 (my version is 1.8.7-72), this code:
foo = lambda do
for j in 1..2
return
end
end
foo.call
crashes with a 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
Why does it do this? However, it seems to run fine on my version of Ruby 1.9.
Edit: it's not just the returning inside a lambda; the following runs fine:
foo = lambda do
return
end
foo.call
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
发生的情况是 lambda 中间的 for 语句在内部转换为块。 在 Ruby 中,块内的 return 语句的范围仅限于其封闭方法。 请考虑以下情况:
运行
bar
时,返回1
,因为return
的作用域为整个bar
方法。 要从块返回,您需要使用next
或break
,它们都带有参数。 考虑一下:此中断使您从块中返回,并阻止任何后续迭代。 在这种情况下,调用
bar
将返回2
,因为迭代器将返回1
和foo[] + 1
> 因此将返回2
。如果所有这些听起来令人困惑,那么要认识到的主要事情是块内的返回范围仅限于周围的方法,并且如果没有周围的方法,则会引发
LocalJumpError
。What's happening is that the for statement in the middle of the lambda is converted internally into a block. In Ruby, return statements inside blocks are scoped to their enclosing method. Consider the following:
When running
bar
,1
is returned, because thereturn
is scoped to the entirebar
method. To return from blocks, you want to usenext
orbreak
, both of which take parameters. Consider:This break returns you from the block, and blocks any subsequent iterations. In this case, calling
bar
would return2
, since the iterator will return1
, andfoo[] + 1
will therefore return2
.If all of that sounded confusing, the main thing to realize is that return inside blocks is scoped to a surrounding method, and absent a surrounding method, a
LocalJumpError
is raised.您可以使用 throw/catch 来转义循环和 lambda 的其余部分
throw
还采用可选的第二个参数,您可以使用它来返回值。you can escape the loop and the rest of the lambda with a throw/catch
throw
also takes an optional second paramter, which you can use to return a value.