Ruby Exceptions
Author: Samuel Williams When: Tuesday, 04 August 2009The following code surprised me:
begin 1 / 0 rescue puts "Rescue" exit ensure puts "Ensure" end
The result of this code is:
Rescue Ensure
Like all things in ruby, there is a way to bypass this:
begin 1 / 0 rescue puts "Rescue" exit! ensure puts "Ensure" end
The result of this code is:
Rescue
One of the interesting side-effects of processing ensure blocks is that we can actually cancel the exit function:
begin
begin
1 / 0
rescue
puts "Rescue"
exit
ensure
puts "Ensure"
1 / 0 # Raise another exception while processing exit
end
rescue
puts "Outer Rescue"
end
puts "More stuff"
The surprising result of this program is:
Rescue Ensure Outer Rescue More stuff
Therefore, even though we asked ruby to exit, because of the second exception, the program kept running! The reason for this is that exit doesn't actually do what it says it does; actually it simply raises the SystemExit exception, which when received at the top level, causes the interpreter to stop.
begin exit rescue SystemExit puts "Caught SystemExit" end
The result of this code is:
Caught SystemExit
This is by design: It means that you can process exit in a way other than exiting a program. For example, in a networking library, you might not want individual connections exiting the entire app, so you can can trap this kind of behaviour and deal with it specifically.
Comments
Please note, you can leave a comment that uses (limited) XHTML and Textile syntax.