Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > InterfaceContract distilled :: how to implement (mostly)

Thread Tools

InterfaceContract distilled :: how to implement (mostly)

T. Onoma
Posts: n/a

1. An InterfaceContract is a guarentee that a class provides
required "respond_to" methods. Ruby can verify this
on either defining or constructor events. So it is a strong
promise with reasonably low overhead.

2. An InterfaceContract may also specify the types of method
parameters. But this requires extra syntax, and Ruby can't
verify these at constructor or defining moments. So it is only
a weak promise, anyway.

3. To overcome the later a runtime TypeChecker is required.
This provides strong promise, but has higher overhead.
To improve performance this could be an option
that can be switched on or off either on the command line
or inline.

4. InterfaceContracts will require type definitions
to specify the base Interfaces. And it has been proposed
that standard built in Ruby classes be used as that basis.

6. Using these base classes amounts to providing a set of
correspoding hollow, immutable replicas of the base classes.
Classes that Implement these are checked to verify that
they fulfill the role of a complete superclass of the
implemented immutables.


1. If there is too much coding overhaed for defining
InterfaceContracts it will get little use. This would
make it rather obscure and thus perhaps not worth
the effort.

2. But this can be addressed by not having special
Interface types. We can just use existing classes.
If we say: implement Klass (in contrast to mixins)
then we are saying that our new class must fullfill
the role of a superclass of Klass, prior to the
instantiation of our new class, or it is not valid.

3. When #implements is invoked a new frozen subclass
of Klass is created, the Interface, and a mixin
is inserted in our new class. So when our new class
is substantiated, the use of super calls the initialize
method of the mixin module which compares the
Interface to self. If it doesn't check-out an
ImplementationError is thrown.

4. This design is not as light weight as the one Sean
has put forth because it checks the interface everytime a
new object, that implements an interface, is created. But the
advantage is that no special hooks are required for dealing
with the dynamic adding or removing of methods to our classes
working to continue to ensure the contract is being kept.
The dynamic nature of Ruby remains intact. Also I think
that if we subsequently freeze our class, we could
have this mixin removed, as it would no longer be needed.
in an enviornemt where InterfaceCnntracts are bing used
freezing calss definition make a lot of sense, and could be
common place. Although this feature would have to be
added to core ruby itself.

5. This design dosen't account for parameter types b/c they
would have only a weak promise any way. So this is best
reserved for a Euphoria like type checker as I have descibed
elsewhere, or re and ost assertion methods as descirbed
by James. Each has advantages and disadvantges. The
Euphoric system has one major advantage in that it can
be integrated with InterfaceContracts such that the types
defined could double for Interface classes, which seems
useful considering the next point.

6. One problem becomes quite appearent when using this tool. That of
Granularity. Ruby's built in classes have too many methods for
this to be very useful. This may indicate that Ruby's classes,
somehow, need to be broken into smaller meaningful chunks, even
if it is merely a matter of namespace dividers inside the class that
have no effect on the class other then to group related methods,
and, of course, a means to reference them from the outside.


class ImplementationError < StandardError

module InterfaceContracts

class Module
def implements(*klasses)
klasses.each do |klass|
InterfaceContracts.class_eval %Q{
unless #{klass} === Class
class #{klass} < #{klass}; end
ifc_str = '[' +
klasses.collect {|k| "InterfaceContracts::#{}" }.join(',')+']'
ifm =
ifm.module_eval %Q{
def initialize(*args)
#{ifc_str}.each do |k|
umeths = k.public_instance_methods(true) - self.public_methods
if umeths != []
raise ImplementationError, + " as " + + "\n" + umeths.sort.join(', ')
class_eval { include ifm }

Example 1:

# this may seem trival but it is a guaranteed super class of String.

class MyClass < String
implements String
def initialize
p "I promise to quack like a String."
def extra; p "extra"; end
m1 = # => "I promise to quack like a String."
m2 = # => "I promise to quack like a String."

Example 2:

# show that the methods of Integer have not been implemented.

class MyClass < String
implements String, Integer
def initialize
p "I promise to quack like a String and Integer."
m1 = # => ImplementationError (see below)

MyClass as InterfaceContracts::Integer (ImplementationError)
+@, -@, abs, ceil, chr, coerce, div, divmod, downto, floor, integer?,
modulo, nonzero?, prec, prec_f, prec_i, quo, remainder, round, step,
times, to_int, truncate, zero?

# notice that the unimplemented methods are listed.


Reply With Quote

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Python Distilled Simon Wittber Python 8 11-07-2006 03:47 AM
Looking for distilled water supplier The Hobbit NZ Computing 27 09-21-2005 06:00 AM
[OT] "UML for Java Programmers" or "UML Distilled" Rogue Chameleon Java 0 10-18-2004 02:27 PM
Distilled wisdom - 2000 or 2003/xp for new MCP? Dev Lunsford MCSA 6 09-11-2003 08:53 AM