如何取消评估所需的 Ruby 文件? (a.k.a.顶级return)
How to cancel evaluating a required Ruby file? (a.k.a. top-level return)
file1
需要 file2
,我希望能够在某些条件下取消评估 file2
而无需退出整个过程。
# file1.rb
puts "In file 1"
require 'file2'
puts "Back in file 1"
# file2.rb
puts "In file 2"
# return if some_conditional
puts "Still in file 2"
当运行file1
时,我想看到的输出是:
In file 1
In file 2
Back in file 1
目标是 Still in file 2
从不打印,而 Back in file 1
打印。 我在 file2
有什么可以做的吗?
我不能在这里使用 exit
/exit!
/abort
因为 Back in file 1
永远不会打印。我可以使用 raise
/fail
,但要做到这一点,我必须更改 file1
和 rescue
失败的 require
。我希望找到一种不涉及更改 file1
.
的方法
更新:
一个"top-level return"特征has been added。
我不知道有什么官方方法可以破解所需的文件,尤其是有几种 require
方法(例如,bundler monkey patches require)
我能想到的最佳解决方案是使用 rubys throw-catch 控制流。我不确定你是否使用条件来确定是否应该 return 早点执行,但这应该能够应对大多数情况
# file1.rb
puts "In file 1"
catch(:done) do
require 'file2' end
puts "Back in file 1"
# file2.rb
puts "In file 2"
throw :done
puts "Still in file 2" # Never gets called
__END__
will not be executed 下面的行。
# file2.rb
puts "In file 2"
__END__
puts "Still in file 2" # Never gets called
是否可以使用一种方法?它仍然会解析该方法,但不会执行。像 :
#file1.rb
puts "In file 1"
require 'file2'
puts "Back in file 1"
a_method
#file2.rb
puts "In file 2"
# <= A
def a_method
puts "Still in file 2"
end
更新:
一个"top-level return"特征has been added。
原版:
核心团队会议中关于新 Ruby 功能的评论者 matt pointed out that Feature 4840, which would do exactly what I'm asking about, has been in discussion since June 2011. Further, the feature was still being discussed as late as November 2015。
设计这样的功能有很多困难;对于优点和缺点的列表,我强烈建议查看讨论。
提议的功能将允许在使用以下任何 top-level 语句时退出所需的文件:
if condition
return
end
while condition
# ...
return
end
begin
# ...
return
rescue
# ...
return
ensure
# ...
return
end
并且在以下语句中它不会退出所需的文件:
class Foo
return # LocalJumpError
end
def foo
return # returns from method, not from required file
end
proc do
return # LocalJumpError
end
x = -> { return } # returns as from lambda, not from required file
由于该功能仍未实现,我已将赏金奖励给 steenslag,以表彰其成功解决问题(如最初所写),如果不是精神的话。
file1
需要 file2
,我希望能够在某些条件下取消评估 file2
而无需退出整个过程。
# file1.rb
puts "In file 1"
require 'file2'
puts "Back in file 1"
# file2.rb
puts "In file 2"
# return if some_conditional
puts "Still in file 2"
当运行file1
时,我想看到的输出是:
In file 1
In file 2
Back in file 1
目标是 Still in file 2
从不打印,而 Back in file 1
打印。 我在 file2
有什么可以做的吗?
我不能在这里使用 exit
/exit!
/abort
因为 Back in file 1
永远不会打印。我可以使用 raise
/fail
,但要做到这一点,我必须更改 file1
和 rescue
失败的 require
。我希望找到一种不涉及更改 file1
.
更新:
一个"top-level return"特征has been added。
我不知道有什么官方方法可以破解所需的文件,尤其是有几种 require
方法(例如,bundler monkey patches require)
我能想到的最佳解决方案是使用 rubys throw-catch 控制流。我不确定你是否使用条件来确定是否应该 return 早点执行,但这应该能够应对大多数情况
# file1.rb
puts "In file 1"
catch(:done) do
require 'file2' end
puts "Back in file 1"
# file2.rb
puts "In file 2"
throw :done
puts "Still in file 2" # Never gets called
__END__
will not be executed 下面的行。
# file2.rb
puts "In file 2"
__END__
puts "Still in file 2" # Never gets called
是否可以使用一种方法?它仍然会解析该方法,但不会执行。像 :
#file1.rb
puts "In file 1"
require 'file2'
puts "Back in file 1"
a_method
#file2.rb
puts "In file 2"
# <= A
def a_method
puts "Still in file 2"
end
更新:
一个"top-level return"特征has been added。
原版:
核心团队会议中关于新 Ruby 功能的评论者 matt pointed out that Feature 4840, which would do exactly what I'm asking about, has been in discussion since June 2011. Further, the feature was still being discussed as late as November 2015。
设计这样的功能有很多困难;对于优点和缺点的列表,我强烈建议查看讨论。
提议的功能将允许在使用以下任何 top-level 语句时退出所需的文件:
if condition
return
end
while condition
# ...
return
end
begin
# ...
return
rescue
# ...
return
ensure
# ...
return
end
并且在以下语句中它不会退出所需的文件:
class Foo
return # LocalJumpError
end
def foo
return # returns from method, not from required file
end
proc do
return # LocalJumpError
end
x = -> { return } # returns as from lambda, not from required file
由于该功能仍未实现,我已将赏金奖励给 steenslag,以表彰其成功解决问题(如最初所写),如果不是精神的话。