在Ruby块中使用'return'

Met*_*aFu 83 ruby lambda return proc-object

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

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

thing {
  return 6 * 7
}
Run Code Online (Sandbox Code Playgroud)

如果我在上面的例子中使用'return',我会得到一个LocalJumpError.我知道这是因为有问题的块是Proc而不是lambda.如果我删除'return',代码就可以工作,但我真的更喜欢在这种情况下使用'return'.这可能吗?我已经尝试将块转换为lambda,但结果是一样的.

MBO*_*MBO 163

只需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
Run Code Online (Sandbox Code Playgroud)
  • return 总是从方法返回,但是如果你在irb中测试这个片段你没有方法,那就是你拥有的原因 LocalJumpError
  • break从块返回值并结束其调用.如果你的块被yieldor 调用.call,那么break也会从这个迭代器中断
  • next从块返回值并结束其调用.如果您的块被yield或调用.call,则将next值返回到yield调用的行

  • 在proc中中断会引发异常 (4认同)
  • 您能否引用从“下一个从块返回值并结束调用”中获取此信息的位置。我想阅读更多相关内容。 (2认同)

mol*_*olf 18

你不能用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
# ...
Run Code Online (Sandbox Code Playgroud)


gio*_*ian 1

事物在哪里被调用?你在班级里吗?

您可以考虑使用这样的东西:

class MyThing
  def ret b
    @retval = b
  end

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

  def example1
    thing do
      ret 5 * 6
      4
    end
  end

  def example2
    thing do
      5 * 6
    end
  end
end
Run Code Online (Sandbox Code Playgroud)