Download this source
# rescue and exceptions
script = "uts \"Hello there doody\""
# try/catch is begin/rescue
begin
eval script
rescue SyntaxError, NameError
# by default, the same implicit is used as in Perl
exName = $!.class.name
puts "Compilation failed: #{exName}: #{$!.to_s}"
rescue StandardError => err
# We can supply the name instead :)
exName = err.class.name
puts "Standard error: #{exName}: #{$!.to_s}"
end
# finally is ensure
begin
eval script
rescue SyntaxError, NameError => err
puts "Compilation failed"
ensure
puts "Cleaning up"
end
# The construct also supports 'else', which is executed between the main body,
# and the 'ensure', only if NO exception was thrown
begin
# fix the script
eval "p#{script}"
rescue SyntaxError, NameError => err
puts "Compilation failed: #{err.class.name}: #{$!.to_s}"
else
puts "Compilation succeeded"
ensure
puts "Cleaning up"
end
# As that example showed, we can fix the broken script thanks to our vast experience
# with the way these things are implemented ;-) So why not account for this 'common
# error' by fixing and retrying the block?
begin
eval script
rescue SyntaxError, NameError => err
# prefix with 'p' if first char is different, then go back to start of block
if script[0,1] != 'p'
puts "Compilation failed: #{err.class.name}: Trying to fix script '#{script}'"
script = "p#{script}"
retry
end
# otherwise, fail
puts "Compilation failed, even after fix: #{err.class.name}: #{$!.to_s}"
else
puts "Compilation succeeded"
ensure
puts "Cleaning up"
end
Running this outputs:
Compilation failed: NoMethodError: undefined method `uts' for main:Object
Compilation failed
Cleaning up
Hello there doody
Compilation succeeded
Cleaning up
Compilation failed: NoMethodError: Trying to fix script 'uts "Hello there doody"'
Hello there doody
Compilation succeeded
Cleaning up

