On Tue, 3 Feb 2009, Thomas Sawyer wrote:

> David A. Black wrote:
>
>> etc. Jay's example with extending an object with two modules, so that
>> the most recent one "wins" (whereas all modules "lose" if the method
>> in question is defined in the singleton class) is very convincing,
>> though again I wouldn't necessarily treat it as a reason never to
>> define a method in the singleton class. I'd say it's more that you
>> want to know what the ramifications of each technique are, and then
>> choose the one you want. In that sense it's analogous (though not
>> identical) to the non-singleton case, where a method defined in a
>> class "wins", for the instances of the class, over definitions in
>> included modules. That can be good, or not; it depends on what you're
>> trying to do.
>>
>> It all comes down to mastery of the order of method lookup, which then
>> allows you to do pretty much any permutation.
>
> Can you think of a good example of where it is NOT good? All I can think
> of is when we need to metaprogram around someone else not using modules.
>
> I'm sure there are occasions to act directly on the singleton, but I've
> come to believe that should be the exception rather than the rule. And I
> think it would behoove Ruby to promote that as the common idiom. We've
> grown accustom to seeing "class << self". But I think it should be
> raising flags instead --"we are doing something very metay here".

I disagree. I think that excessive meta-ness is to a large extent in
the eye of the beholder. The objects don't know that there's anything
"meta" about what they're being asked to do (resolve a message into a
method, by searching along their lookup path), and the class keyword
doesn't care whether you use the "<< obj" notation or the "MyClass"
notation.

Jay's example of extending an individual object twice is interesting,
but I don't think I've ever actually had to do it. And the only
problem is mixing the two techniques:

   class << obj
     def x
     end
   end

   module M
     def x
     end
   end
   obj.extend(M)   # obj.x is still the first one

Since you can always reopen the singleton class and redefine the
method, using the singleton class in the first place doesn't mean that
you're stuck with the original method definition.

I think #extend is highly underutilized. It's one of my favorite Ruby
techniques. I just don't feel that it has to be in a death-struggle
with any other techniques.


David

-- 
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Coming in 2009: The Well-Grounded Rubyist (http://manning.com/black2)

http://www.wishsight.com => Independent, social wishlist management!