January 2010

Continue that exception

Imagine a world with Exception#continue:

10.times do |i|
  begin
    raise "OH NO!"
    puts "OH YES! #{i}"
    i += 1
  rescue => err
    if i < 5
      err.continue
    else
      raise err
    end
  end
end

Oh, that’s right. This is Ruby. Forty lines later:

class Exception
  class NoContinuation < StandardError
  end
  
  attr_accessor :continuation
  
  def continue
    raise NoContinuation unless continuation.respond_to?(:call)
    continuation.call
  end
end

module NeverGonnaLetYouDown
  def raise(exception = RuntimeError, string = nil, array = caller)
    # With a single String argument, raises a
    # RuntimeError with the string as a message. 
    if exception.is_a?(String)
      string = exception
      exception = RuntimeError
    end
    
    callcc do |cc|
      obj = exception.exception(string)
      obj.set_backtrace(array)
      obj.continuation = cc
      super obj
    end
  end
  
  def fail(exception = RuntimeError, string = nil, array = caller)
    raise(exception, string, array)
  end
end

class Object
  include NeverGonnaLetYouDown
end

View Comments

December 2009

Temple

July 2009

Parkaby

June 2009

Copy'n'Paste

May 2009

GitHub.js

March 2009

Nokogirl

February 2009

Change

January 2009

Tailin' Ruby

December 2008

Copy Folders to a Branch

October 2008

Morse.rb

September 2008

It's a Gash, Gash, Gash

August 2008

Tribute

August 2008

SuperIO

June 2008

Ruby Fishy Edition

April 2008

Moving to Nginx

April 2008

Thank You!

March 2008

RE: Haiku.rb

March 2008

Haiku.rb

February 2008

A Better to_hash

February 2008

A Trip into Random

February 2008

Introducing Gemify