Thursday, December 3, 2009

The Exception to global ruby variables

Global variables are often the over looked cousin of ruby variables. If you have never used them before, here is a quick breakdown



Today I took a closer look as to how they are used. I have seen a lot of ruby code that uses "$!" to refer to a caught exception. Simple example:



begin
raise "boom"
rescue
logger.error($!)
end
view raw gistfile1.rb hosted with ❤ by GitHub


Well, today, as I was trying to write a style guide for OtherInbox, I started to get really concerned about the thread safety of such code. Since global variables are accessible by any thread, there appeared to be a pretty clear thread-safety issue with using $! to refer to an exception. I was ready to scrub the codebase and rewrite everything to look like this:



begin
raise "boom"
rescue StandardError => e
logger.error(e)
end
view raw gistfile1.rb hosted with ❤ by GitHub


Prior to jumping off the deep end, I discussed this with the Capital Thought team. After a rather lengthy discussion about the proper way we should all be handling exceptions (which I hope to share in the future), I wrote a quick test to see if there was a thread safety issue or not.



threads = []
threads << Thread.new do
begin
raise "boom"
rescue
puts $!
sleep(1)
puts $!
end
end
threads << Thread.new do
begin
raise "pow"
rescue
puts $!
end
end
threads.each { |t| t.join }
view raw gistfile1.rb hosted with ❤ by GitHub


If you run this script, it will output "boom, pow, boom". This clearly shows that although "$" defines a global variable in the case of $ERROR_INFO ($!), it is has a local scope.

No comments:

Post a Comment