On 23-Feb-08, at 5:36 PM, Avdi Grimm wrote:

> On Sat, Feb 23, 2008 at 5:23 PM, Eric Mahurin  
> <eric.mahurin / gmail.com> wrote:
>>

>> * adding new (or perceived missing) functionality (methods) to a  
>> class.  The
>> traditional solution would be to just inherit from the class and  
>> use the
>> derived class instead where you want this new functionality.  Since  
>> you
>> can't inherit from some classes (i.e. immediates, a problem with the
>> language IMHO), you can instead use something like Forwardable  
>> instead.
>
> Indeed.  The irony here is that Ruby is perhaps the easiest language
> in the world to implement delegation in.  I'm planning on writing a
> series of posts on alternatives to monkey patching, and delegation is
> going to be one of the first techniques I talk about.

Okay, let's be a little bit careful here. There are at least two  
distinct meanings of 'delegate' in the OO world and people seem to  
flip between them in the same paragraph, even sentence. The seemingly  
most common use is as a synonym for 'forwarding' which is the design  
pattern where a second object provides the implementation of a missing  
method. The original use was as an alternative to inheritance, it's a  
lot like the other meaning but with the crucial difference that 'self'  
is the first object not the second (so if you call a method or use an  
instance variable in the delegated implementation the first object is  
checked not the second).

Unless there's something in Ruby that I don't know about then the  
inheritance-equivalent use is not so easily implemented in Ruby. The  
effect of monkey patching is more like this meaning of 'delegation'  
than it is to the design pattern (in fact, I tend to think of MP as a  
kind of inheritance).

Anyway...

MP is a very powerful technique. Powerful techniques are open to  
abuse, very powerful even more so.

So how do you constrain power? Well you can restrict its use trying to  
prevent abuse at the cost of interfering with perfectly valid uses. Or  
you can make it as general as possible leaving the possibility of  
abuse completely unrestricted, but at the same time leaving the valid  
uses as unrestricted as possible.

This is kind of like the arguments around static typing. If this  
analogy holds, then Ruby has already expressed its position. Dynamic  
languages in general have expressed their positions.

Personally, I like dynamic languages.

Ruby isn't alone in this. Python has come up already. But there are  
other languages that do this, including Smalltalk and Common Lisp/CLOS.

What I think would be nice in Ruby is that the warning flag (-w) would  
go a little further and warn the programmer when a class is reopened  
(and where).

Aside from that, there isn't a lot to argue with in your blog posting.  
Your points individually are fine and quibbling over insignificant  
details on a mailing list is a waste of time (though it might be ideal  
in a pub :-) In other words, I don't disagree with anything you say  
until you start drawing conclusions. I *like* monkey patching and I  
approve of its proper use. Furthermore, I don't special case the abuse  
of MP, it is just like any other abuse of a feature: bad.

Cheers,
Bob


----
Bob Hutchison                  -- tumblelog at http://www.recursive.ca/so/
Recursive Design Inc.          -- weblog at http://www.recursive.ca/hutch
http://www.recursive.ca/       -- works on http://www.raconteur.info/cms-for-static-content/home/