# Cond: Resolve errors without unwinding the stack

**URL:** <https://www.ruby-forum.com/t/cond-resolve-errors-without-unwinding-the-stack/163606>\
**Category:** Ruby\
**Created:** [March 23, 2009, 3:32am UTC](https://www.ruby-forum.com/t/cond-resolve-errors-without-unwinding-the-stack/163606 "2009-03-23T03:32:09Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![noagenda](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/8c91f0/32.png) [@noagenda](https://www.ruby-forum.com/u/noagenda)\
**Post date:** [March 23, 2009, 3:32am UTC](https://www.ruby-forum.com/t/cond-resolve-errors-without-unwinding-the-stack/163606/1 "2009-03-23T03:32:09Z")

</div>

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  
end  
raise ZeroDivisionError if y == 0  
x/y  
end  
end

handling do  
handle ZeroDivisionError do  
invoke\_restart :return\_this\_instead, 42  
end  
puts divide(10, 2) # =\> 5  
puts divide(18, 3) # =\> 6  
puts divide(4, 0) # =\> 42  
puts divide(7, 0) # =\> 42  
end

== Install

% gem install cond  
or  
% 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  
behavior.

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  
called.

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.

[http://video.google.com/videoplay?docid=448441135356213813#46m07s](http://video.google.com/videoplay?docid=448441135356213813#46m07s)

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

[http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html](http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html)

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  
end

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

  raise ZeroDivisionError if y == 0
  x/y
end

puts result # => 42

```

end

== 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.handling.

+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

- Documentation: [http://cond.rubyforge.org](http://cond.rubyforge.org)
- Rubyforge home: [http://rubyforge.org/projects/cond/](http://rubyforge.org/projects/cond/)
- Download: [http://rubyforge.org/frs/?group\_id=7916](http://rubyforge.org/frs/?group_id=7916)
- Repository: [GitHub - quix/cond: Condition system for handling errors in Ruby](http://github.com/quix/cond/tree/master)

==

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
