【问题标题】:Does Ruby's $! hold value only in rescue block?Ruby的$!仅在救援块中保持价值?
【发布时间】:2015-03-07 07:23:55
【问题描述】:
begin
  raise 'foo'
rescue
  puts $!.inspect # => #<RuntimeError: foo>
ensure
  puts $!.inspect # => nil
end
puts $!.inspect # => nil

谷歌搜索,但没有找到明确的答案。

只是想确认$! 的生命周期(?),它是否只在rescue 块内保持价值?

【问题讨论】:

  • 我相信是这样,但我似乎无法确认。
  • 你的 ensure 行和它后面的行使它比需要的更复杂。
  • 删除救援块并检查它只是确保...

标签: ruby rescue


【解决方案1】:

$! 在救援块中有错误,如果没有救援块,则在确保块中:

begin
  raise 'foo'
ensure
  puts $!.inspect # => #<RuntimeError: foo>
end

$! 在其他任何地方都有 nil 的值。

【讨论】:

  • 谢谢!很高兴知道。可能会接受这个作为答案,请再等一天确定。
【解决方案2】:

不,只读变量$! 在任何地方都是可见和可用的,它保存nil 的值,但救援块除外。

每个线程也是唯一的。它是当前异常(English 库将其称为 $ERROR_INFO),一旦获救,它就会重置为 nil,除非它被重新引发,否则它会恢复为当前异常。

从一个没有其他行的文件中,我们可以看到确实是 $!可见。

puts defined?($!)
puts $!.inspect  

irb(main):001:0> defined?($!)
=> "global-variable"
irb(main):002:0> $!
=> nil
irb(main):003:0>

而在 IRB 中,我们可以看到它是已定义且可见的。

这真的一点也不(或者说不应该)令人惊讶,因为$ 指定它是“全局变量”,因此是全局可见的。

我无法找到它不可见的地方。即使在 BasicObject 中也是可见的。

irb(main):001:0> class BasicObject
irb(main):002:1>   def is_it_visible
irb(main):003:2>     defined?($!)                                                                                                 
irb(main):004:2>   end                                                                                                            
irb(main):005:1> end                                                                                                              
=> :is_it_visible
irb(main):006:0> BasicObject.allocate.is_it_visible
=> "global-variable"
irb(main):007:0>

【讨论】:

  • 抱歉,我的措辞让您感到困惑。我应该问“$!是否只在救援块内保持价值?”。
  • 不,你的问题很清楚。没有什么让我感到困惑的。正如您在代码中演示的那样,它在这些块之外保存 nil 的值。
猜你喜欢
  • 2012-02-26
  • 2023-01-13
  • 1970-01-01
  • 2020-08-31
  • 1970-01-01
  • 1970-01-01
  • 2017-03-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多