From: "Matthias Lampert" <ml / sph.de>
> I see.  The feature of a guaranteed common interface for derived
> classes is only needed for strongly typed languages where a method
> needs to know the type it is passed to as a parameter.
>
> Seems Bruce Eckel has taught me `Thinking in Java' too
> intensively! ;-)

Yes, thinking in Ruby is closer to thinking in Smalltalk than thinking in
Java and many of the Smalltalk patterns and best practices translate to Ruby
very easily.

As you say, abstract interfaces in Java are used to define the protocol or
contract that client objects expect to be implemented by objects they use.
However, they are not really very good at defining a contract -- they only
define the method signatures that an object guarantees to implement, but not
the pre/postconditions and invariants that the object guarantees to provide,
or the order in which methods are allowed to be called.  The equivalent of
abstract interfaces in dynamically typed languages are "object protocols".
Protocols are not declared in Ruby, and have to be documented somehow.  A
simple example of a protocol is the constraints on the implementation of the
Object::eq? and Object::hash methods.  This protocol is described in the
documentation for the Object class. So, having no abstract interfaces in
Ruby is really not a great drawback, and has the advantage that protocol
definitions are orthogonal to inheritance of functionality.

IMHO, the best way to document protocols is to use unit tests and mock
objects.  This gives you a precise, executable definition of protocols that
can be used to automatically test objects for conformance to those
protocols.  I have written a package for writing mock objects with the RUnit
framework which I will release in the next few days.  I'll announce it to
this mailing list and add it to the RAA.