在主要环境中`return`

问题描述 投票:2回答:1

当我在irb或pry的主环境中运行以下内容时,

return "foo"

我明白了:

LocalJumpError: unexpected return

这是预料之中的。但是,当我在单独的文件foo.rb中编写此代码时,并执行:

$ ruby foo.rb

在控制台中,它终止没有任何错误消息。

后一种情况发生了什么?

我认为可能会默默地处理引发的错误,并在单独的文件中尝试以下内容:

begin
  return "foo"
rescue Exception => e
  p e
end

并从控制台执行它,但这也导致没有错误。

当我将代码放在诸如模块的环境中时,它返回错误:

module A
  return "foo" # >> Invalid return in class/module body
end
ruby return main
1个回答
3
投票

顶级返回作为ruby 2.4.0中的一个特性添加:https://bugs.ruby-lang.org/issues/4840

release announcement中从未提及它,但你可以在更详细的news post中看到它列在“语言变化”下。

如果您在ruby版本return "foo"中运行包含< 2.4.0的文件,您确实会看到如下错误:

foo.rb:1:in `<main>': unexpected return (LocalJumpError)

预期的用例(从上面的链接可以看出)是“取消require” - 例如如果文件是特定于平台的,例如:

require "test/unit"

return unless /mswin|cygwin|mingw|bccwin/

# ...

对提议的语法和行为进行了大量讨论和辩论;但是通过阅读实现的test cases,可能最好地理解所选择的实现:

def test_return_toplevel
  feature4840 = '[ruby-core:36785] [Feature #4840]'
  code = <<~'CODE'
  return; raise
  begin return; rescue SystemExit; exit false; end
  begin return; ensure exit false; end
  begin ensure return; end
  begin raise; ensure; return; end
  begin raise; rescue; return; end
  return false; raise
  return 1; raise
  CODE
  all_assertions(feature4840) do |a|
    code.each_line do |s|
      s.chomp!
      a.for(s) {assert_ruby_status([], s)}
    end
  end
end

由于在像return这样的REPL中写pry不是“顶级”,这导致LocalJumpError而不是上面的“顶级return”的特殊行为。

© www.soinside.com 2019 - 2024. All rights reserved.