在Ruby块中怎么使用'return'?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (8)

我正在尝试将Ruby 1.9.1用于嵌入式脚本语言,以便将“最终用户”代码写入Ruby块中。与此相关的一个问题是,我希望用户能够在块中使用“返回”关键字,使得他们不需要担心隐式返回值。考虑到这一点,我希望能够做到:

def thing(*args, &block)
  value = block.call
  puts "value=#{value}"
end

thing {
  return 6 * 7
}

如果我在上面的例子中使用'return',我得到一个LocalJumpError。我知道这是因为所讨论的块是Proc而不是lambda。如果我删除'return',代码将起作用,但我更希望能够在这种情况下使用'return'。这可能吗?

提问于
用户回答回答于

你不能在Ruby中这样做。

return关键字总是从在当前上下文中的方法或λ返回。在块中,它将从定义闭包的方法返回。它不能从调用方法或lambda 返回。

Rubyspec表明,这确实是Ruby的正确的行为(当然不是真正的实现,但目的是为C Ruby的全兼容):

describe "The return keyword" do
# ...
describe "within a block" do
# ...
it "causes the method that lexically encloses the block to return" do
# ...
it "returns from the lexically enclosing method even in case of chained calls" do
# ...
用户回答回答于

直接next

$ irb
irb(main):001:0> def thing(*args, &block)
irb(main):002:1>   value = block.call
irb(main):003:1>   puts "value=#{value}"
irb(main):004:1> end
=> nil
irb(main):005:0>
irb(main):006:0* thing {
irb(main):007:1*   return 6 * 7
irb(main):008:1> }
LocalJumpError: unexpected return
        from (irb):7:in `block in irb_binding'
        from (irb):2:in `call'
        from (irb):2:in `thing'
        from (irb):6
        from /home/mirko/.rvm/rubies/ruby-1.9.1-p378/bin/irb:15:in `<main>'
irb(main):009:0> thing { break 6 * 7 }
=> 42
irb(main):011:0> thing { next 6 * 7 }
value=42
=> nil
  • return 总是从method返回,但如果你在irb中测试这个片段,你没有method,那就是你为什么要这样做的原因 LocalJumpError
  • break返回块的值并结束其调用。如果你的块被yield.call调用,那么break也会从这个迭代器中断开
  • next返回块的值并结束其调用。如果你的块被yield或.call调用

然后next返回值到yield被调用的行

扫码关注云+社区