[Q] How would you do method extensions (sometimes called class extensions) in Ruby?

From: Markus Gaelli <gaelli@emergent.de>
Date: August 31, 2006 11:07:26 PM GMT+02:00
To: ruby-core@ruby-lang.org
Subject: [Q] How would you do method extensions (sometimes called class extensions) in Ruby?

Hi List,

(1) The Problem: Bridge Gap between Tests and Documentation with Executable Examples
May I introduce myself shortly: I am a long-term OOer using mainly Smalltalk until now [0] - and I am interested in bridging the gap between documentation (static, bound (comments possible for classes and methods), often outdated) and unit testing (dynamic, unbound [2], up to date) by the metaphor of examples.

(2) The Concept
I'd like to be able to see exemplified calls for methods ("method examples") - and compose new method examples using example instances of classes - which in turn are created by "method examples" [3]

(3) The Proof of Concept
I have some prototypes for "Eg" in Smalltalk [3], but wonder how it would be possible to do something like this in Ruby.

(4) My Approach in Smalltalk: Relying on Conventions and Method Extensions

(4.1) Exemplifying Classes
The easiest solution to bind examples at least to their classes (where they should give an exemplified instance of) is by making them factory methods of them on the class side. At least in Smalltalk you can see this pattern a lot (usually these class methods also start with "example..."), I am sure Ruby folks do something similar.

(4.2) Exemplifying and Testing Methods
I just say that the last method called in these class methods is the one exemplified by this example. So this is how I can bind the methods to their "method examples" in a light-way and very readable manner.

If the method under test (yes, the last one called in the factory method / example method) has some postconditions I would declare this method to be a "checked method example".
If there are some assertions in the "method example" itself, I take the last method called before the assertions as the tested/exemplified method. I call these kind of "commands" "method tests".
Note that these "method commands" do return an instance of the class they are bound to. This is my invariant for storing them and also ensures that the instances they create can be reused by higher-level examples/ tests. I do not believe tests should be "void" as JUnit, one only needed to call the highest level tests, which in turn can call lower level ones. And yes - all tests shall be side effect free, and everything but the return value should get garbage collected after a test is over.

(5) Finally: My Concrete Problem
As you can see I am heavily relying on conventions to keep the code readable, but still machine parsable. But for doing so I need to denote these "method commands" (including "method examples", "checked method examples" and "method tests") as being of this kind. Besides many people do not like the idea to deploy their code together with tests, so they needed to be separable.

This is fine in Smalltalk, as we have method extensions, which scope allow Smalltalkers to add methods to classes in packages, in which these classes have _not_ been originally defined, but how would you do this in Ruby?

I am aware of Singleton Methods, but as they can extend instances, (how) can I extend classes without changing their original class definition in Ruby?

I would be very grateful for some help, or pointers - certainly I wouldn't mind if somebody stole this idea, actually I'd love to see "Eg" ported to Ruby, but I am lacking a bit time to do it myself: I have to finish my PhD soon and then a Smalltalk (Seaside) job to start.
- But I do would like not to look too Smalltalk-Snobbish and include some help in my PhD to any guys of other fine languages, who decided some day, that this might be a good idea.



[1] http://www.iam.unibe.ch/~scg/cgi-bin/scgbib.cgi?query=gaelli
[2] Markus Gaelli, Michele Lanza and Oscar Nierstrasz, “Towards a Taxonomy of SUnit Tests,” Proceedings of ESUG 2005 (13th International Smalltalk Conference), September 2005.
[3] Markus Gaelli, Oscar Nierstrasz and Stéphane Ducasse, “One-Method Commands: Linking Methods and Their Tests,” OOPSLA Workshop on Revival of Dynamic Languages, October 2004.


Begin forwarded message: