Forum: Ruby Cond: Resolve errors without unwinding the stack

Announcement (2017-05-07): is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see and for other Rails- und Ruby-related community platforms.
Efdb04c4dac4a962d86e25361f8fd450?d=identicon&s=25 James M. Lawrence (quix)
on 2009-03-23 03:32
Hello --

Here is a portion of the readme for this new project.  For those
unfamiliar with condition systems, I recommend watching a few minutes of
Seibel in the video mentioned below.

= Cond

== Description

Resolve errors without unwinding the stack.

== Synopsis

  require 'cond'
  include Cond

  def divide(x, y)
    restartable do
      restart :return_this_instead do |value|
        return value
      raise ZeroDivisionError if y == 0

  handling do
    handle ZeroDivisionError do
      invoke_restart :return_this_instead, 42
    puts divide(10, 2)  # => 5
    puts divide(18, 3)  # => 6
    puts divide(4, 0)   # => 42
    puts divide(7, 0)   # => 42

== Install

  % gem install cond
  % ruby install.rb [--uninstall]

== Overview

Cond allows errors to be handled near the place where they occur,
before the stack unwinds.  It offers several advantages over
exceptions while peacefully coexisting with the standard exception

The system is divided into two parts: _restarts_ and _handlers_.  When
+raise+ is called and there is a matching handler for the error, the
normal mechanism of unwinding the stack is suspended while the handler
is called instead.  At this time, the handler may invoke one of the
available restarts.

A handler may find a way to negate the problem and, by invoking a
restart, allow execution to continue from a place proximal to where
+raise+ was called.  Or a handler may choose to allow the exception to
propagate in the usual unwinding fashion, as if the handler was never

Cond is 100% compatible with the built-in exception-handling system.
We may imagine that Ruby had this handler/restart functionality from
the very beginning, but everyone had forgotten to write restarts.  And
since no restarts were available, no handlers were written.

== Background

Cond is stolen from the Common Lisp condition system.

Peter Seibel discusses the advantages of handlers and restarts in the
following video.  I have fast-forwarded to the most relevant part,
though the whole talk is worthwhile.

The example he shows is taken from his book on Lisp,

See readmes/seibel_pcl.rb for a Ruby translation.

== Synopsis 2.0

  x, y = 7, 0

  handling do
    handle ZeroDivisionError do |exception|
      invoke_restart :return_this_instead, 42

    result = restartable do
      restart :return_this_instead do |value|
        leave value

      raise ZeroDivisionError if y == 0

    puts result  # => 42

== Technical Notes

Cond has been tested on MRI 1.8.6, 1.8.7, 1.9, and the latest jruby.

Each thread keeps its own list of handlers, restarts, and other data.
All operations are fully thread-safe.

It is not required to <tt>include Cond</tt>.  The includable methods
of +Cond+ are <tt>module_function</tt>s and are thus callable via e.g.

+Cond+ nests private modules and classes inside Cond::CondPrivate in
order to improve the hygiene of <tt>include Cond</tt> and encourage
its use.

Except for the redefinition +raise+, Cond does not silently modify any
of the standard classes

== Links

* Documentation:
* Rubyforge home:
* Download:
* Repository:


I am open to suggestions on anything from syntax to terminology.  For
example I experimented with a "body" block so that the the main code
could appear before the handlers and restarts.  And I once used "on" to
replace both "handle" and "restart", e.g., "on ZeroDivisionError do

James M. Lawrence
This topic is locked and can not be replied to.