On Sun, Feb 23, 2003 at 04:24:37AM +0900, Mark Wilson wrote:
> 
> On Saturday, February 22, 2003, at 09:31 AM, Gavin Sinclair wrote:
> 
> >[snip]
> >It's perfectly obvious at a glance to me.  True, I've faced difficulty
> >with such concepts in the past (at one point, I didn't understand the
> >class << self business), but working through those difficulties is
> >necessary to become proficient in Ruby.
> >
> >Not that I'm suggesting that difficult code be written for the sake of
> >it.  Only that there's no point shying away from complex-seeming
> >constructs which, thankfully, are part of the consistency of the
> >language.
> >[snip]
> 
> Gavin,
> 
> Your message raises the obvious question for me -- given that I don't 
> understand the 'class << self' business -- what is the meaning and 
> usage of 'class << self'? Please help me truly understand. Thanks.

(skip as much as required :)

class << someobj
end

allows you to add singleton methods to one object (that is, add methods
to its singleton class).

>> a = "aaa"
=> "aaa"
>> class << a
>>   def foo
>>     puts "ho" * 3
>>   end
>> end
=> nil
>> a.foo
hohoho
=> nil

Classes are objects too

>> class A; end
=> nil
>> A.id
=> 538275918

and as such you can add singleton methods to them:

>> class << A
>>   def bar
>>     puts "bar" * 4
>>   end
>> end
=> nil
>> A.bar
barbarbarbar
=> nil

Now, inside class A; ....; end, self refers to the class object (that of
class Class :)

>> A.id
=> 538275918
>> class A; self.id; end
=> 538275918
>> class A; self.class; end
=> Class

Now we use both 'class << someobj' and the fact that, inside the 
'class SomeClass; .... ; end' construct, self refers to the class. We
thus add singleton methods, that is, class methods 

>> class A
>>   class << self
>>     def baz
>>       puts "baz " * 4
>>     end
>>   end
>> end
=> nil
>> A.baz
baz baz baz baz
=> nil

So that idiom corresponds to doing

>> def A.baz2
>>   puts "baz " * 4
>> end
=> nil
>> A.baz2
baz baz baz baz
=> nil

One cool thing about singleton method definitions is that they can be
nested inside other method defs:

>> def foo(a)
>>   def a.babar
>>     puts "I am #{self.id}"
>>   end
>> end
=> nil
>> b = "fdgdfgf"
=> "fdgdfgf"
>> foo(b)
=> nil
>> b.babar
I am 538152868
=> nil

That is equivalent to

>> def foo(a)
>>   class << a
>>     def babar
>>       puts "My id is #{self.id}"
>>     end
>>   end
>> end
=> nil
>> b = "abcd"
=> "abcd"
>> foo(b)
=> nil
>> b.babar
My id is 538276118
=> nil

One reason to prefer 'class << obj' over 'def obj.' is that it is
possible to capture the singleton class that way:

>> class << b; self; end
=> String   # reported as 'String' but it is actually the singleton class of b!

Imagine for instance that you don't want the singleton class (and therefore
the singleton methods) of an object to be modified; you'd do

class << someobj; self.freeze; end

-- 
 _           _                             
| |__   __ _| |_ ___ _ __ ___   __ _ _ __  
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
	Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

-  long    f_ffree;    /* free file nodes in fs */
+  long    f_ffree;    /* freie Dateiknoten im Dateisystem */
	-- Seen in a translation