# Handshake, an informal contract system for Ruby

**URL:** <https://www.ruby-forum.com/t/handshake-an-informal-contract-system-for-ruby/103605>\
**Category:** Ruby\
**Created:** [May 8, 2007, 10:54am UTC](https://www.ruby-forum.com/t/handshake-an-informal-contract-system-for-ruby/103605 "2007-05-08T10:54:45Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brian\_Guthrie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/7bcc69/32.png) [@Brian\_Guthrie](https://www.ruby-forum.com/u/Brian_Guthrie)\
**Post date:** [May 8, 2007, 10:54am UTC](https://www.ruby-forum.com/t/handshake-an-informal-contract-system-for-ruby/103605/1 "2007-05-08T10:54:45Z")

</div>

Handshake is an informal contract system for Ruby. It allows  
developers to apply clear, concise, and enforceable interfaces to  
classes, in three forms:

- method signatures
- class invariants
- pre- and post-conditions

Note that Handshake will only enforce checked contracts if the $DEBUG  
flag is set to true (ruby -d).

Method signature contracts are applied in the following way:

class Foo  
include Handshake

```
contract [all, acceptable, arguments] => return_value
def method(arg, ...) ...

```

end

Signature contracts accept clauses, which are defined as any object  
that implements the === method. When specified with a symbol, they  
will be applied the named method; when specified without one, they  
will be applied to the next defined method. Handshake comes with a  
number of useful clauses predefined:

contract :foo, any?(String, 0…5) =\> Symbol  
contract :sum, many?(Integer) =\> Integer  
contract :deposit, positive\_n? =\> Integer

It can also apply contracts to varargs and anonymous blocks:

contract [String, [ Integer] ] =\> anything  
def foo(str, \*ints) …

contract :each, Block(String =\> anything) =\> many?(String)

In addition, users can define their own custom project-specific  
clauses very easily. See the RDoc for Handshake::ClauseMethods for  
more information.

Class invariants accept a message and a block, which is expected to  
return a boolean value. Their value is checked before and after each  
method invocation and are scoped to allow checking of instance  
variables and private methods.

class NonEmptyArray \< Array  
include Handshake  
invariant(“should never be empty”) { not empty? }  
end

Pre- and post-conditions allow for grouping common sets of assertions,  
typically those that require checking arguments against one another.  
All Test::Unit assertions are available, although they raise a  
Handshake::ContractViolation exception here upon failure.

before do |first\_half, second\_half|  
assert\_equal 10, first\_half.length + second\_half.length  
end  
def accepts\_ten\_items(first\_half, second\_half) …

Handshake is implemented by aliasing the new method of any class that  
includes it. The modified new method returns a proxy object in place  
of the original object that looks, acts, and feels like the real  
thing. It acts as a barrier, and all method invocations that cross  
the barrier are checked against the defined contracts. It differs in  
this manner from other Ruby DBC-style systems, which generally alias  
each contract-checked method as necessary. Because of both this and  
its grave irrelevance to a Rails context, I wouldn’t recommend trying  
to use Handshake with any Rails projects.

Handshake is written in pure Ruby, is available as open source under  
the same license as Ruby, and is installable as a gem (latest  
version=0.3.0). It lives at [http://rubyforge.org/projects/handshake](http://rubyforge.org/projects/handshake),  
and the RDoc is available at [http://handshake.rubyforge.org](http://handshake.rubyforge.org).

I’d love to hear any comments, criticisms, and suggestions. I’m also  
presenting Handshake tonight at the Boston Rubygroup and figured,  
well, I should probably announce the silly thing on ruby-talk first.

Brian Guthrie  
removed\_email\_address@domain.invalid

> **[Gears within Gears: Seek simplicity, and mistrust it | Brian Guthrie](http://blog.brianguthrie.com)**
>
> Gears within Gears: Seek simplicity, and mistrust it | Brian Guthrie
