Edit: Original question was:
Is Ruby's $!
value only visible in rescue block?
begin
raise 'foo'
rescue
puts $!.inspect # => #<RuntimeError: foo>
end
puts $!.inspect # => nil
Googled around but didn't find a clear answer.
Just want to confirm the visibility of $!
, is it only accessible inside a rescue
block?
No, the read only variable $!
is visible and available every where, and holds the value of nil
except in rescue blocks.
It is also unique to each thread. It is the current exception (the English
library calls it $ERROR_INFO
), and it is reset to nil
once rescued, unless it is re-raised, then it is back to being the current exception.
From a file that has no other lines in it, we can see that indeed $! is visible.
puts defined?($!)
puts $!.inspect
irb(main):001:0> defined?($!)
=> "global-variable"
irb(main):002:0> $!
=> nil
irb(main):003:0>
And in IRB we can see that it is defined and visible.
This really is not (or rather should not be) surprising at all, as the $
designates that it is "global variable" and as such is globally visible.
I have not been able to find where it is not visible. Even in BasicObject, it is visible.
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>
I should add that it is one of the "read only" variables as well. Trying to assign to it would result in a NameError with a message explaining that it is a read-only variable.
ensure
line and the line following it is making it more complex than needed. – Dumfound