Ruby的$!仅在救援区保持价值?

时间:2015-01-09 01:51:24

标签: ruby rescue

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

用Google搜索,但没有找到明确的答案。

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

2 个答案:

答案 0 :(得分:6)

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

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

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

答案 1 :(得分:0)

不,只读变量$!是可见的,并且每个地方都可用,并保留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中,我们可以看到它已被定义并可见。

这真的不是(或者说不应该)令人惊讶,因为$表示它是&#34;全局变量&#34;因此在全球范围内可见。

我无法找到不可见的地方。即使在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>