Here's another go at it using continuations:

% cat try_catch_throw.rb
class Flow
   def initialize(parent = nil)
     @exceptions = []
     @parent = parent
     @uncaught_exception = nil
   end
   def try(&block)
     @try_block = block
   end

   def throw(exception)
     caught = @exceptions.each do |key, value|
       if key === exception
         value.call(exception)
         break true
       end
     end

     unless caught == true
       if @parent
         @parent.throw(exception)
       else
         @uncaught_exception = exception
       end
     end
     @cc.call
   end

   def finally(&block)
     @finally = block
     self
   end

   def catch(exception, &block)
      @exceptions << [exception, block]
      self
   end
   def go
    callcc { |@cc| @try_block.call }
    if @finally
     @finally.call
    end
    if @uncaught_exception
      STDERR.puts "Uncaught exception: #{@uncaught_exception}"
      exit(1)
    end
   end

end




% cat test_flow.rb
require 'try_catch_throw'


handling2 = Flow.new
handling2.try {
   handling3 = Flow.new(handling2)
   handling3.try {
     puts "Nested try"
     handling3.throw "ERROR! in handling3"
   }
   handling3.go
}

handling2.catch(String) do |exception|
   puts "handling2 Caught exception: #{exception}"
end

handling2.go

handling = Flow.new

handling.try {
   puts "Hello"
   handling.throw "ERROR!"
   puts "World"
}
handling.finally {
   puts "Finally"
}

handling.go


% ruby test_flow.rb
Nested try
handling2 Caught exception: ERROR! in handling3
Hello
Finally
Uncaught exception: ERROR!

At first I tried to do it without continuations but I couldn't think  
of a way to do so. Also the nesting is explicit which has the  
advantage of not using global vars and the disadvantage of excessive  
typing.