Cond: Resolve errors without unwinding the stack

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 include Cond. The includable methods
of +Cond+ are module_functions and are thus callable via e.g.

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

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

== Links


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 forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs