Understanding class << self

Ruby Add comments

Excerpted from:

http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html

Disclaimer: Enjoy with a huge grain of chunky bacon…

Objects (instances of classes) DO NOT STORE methods, objects only store VARIABLES, instance variables.

METHODS are stored IN THE CLASS. In this sense “a class is an object” is not quite true, objects (instances) and classes (the method store) are DIFFERENT! However, to the PROGRAMMER a class is an object after all, because he can store variables in a class. Duh.

What about metaclasses?

_why: <a metaclass is> “a CLASS which an OBJECT uses to redefine itself”

Effectively this lets you add METHODS, which are usually in the CLASS, to an OBJECT (instance).

so

class << self
[define some methods]
end

means:

Give the current INSTANCE (named self) its own little set of METHODS and store them in a METACLASS (named class) or put differently: ASSOCIATE the current INSTANCE with an (anonymous, singleton bla bla) METACLASS. Ruby calls this METACLASS virtual class, a CLASS ATTACHED to an OBJECT instance. It can also be called eigenclass and numerous other things. Don’t be confused by the <<, it’s more like

(anonymous meta)class <ASSOCIATE WITH> self

This is the so called SINGLETON syntax.

Now the OBJECT (instance) can use these methods as ITS OWN, so called SINGLETON methods. It’s called singleton because there can be only ONE METACLASS attached to an OBJECT, which within the class definition is of type class.

These singleton methods INTERCEPT all calls further up the inheritance chain (important for “reopening” and “overriding” parent class METHODS).

OK, now for the kicker which puts the meta in meta:

CLASSES <ARE> OBJECTS, because they are INSTANCES of Class

So classes can hold INSTANCE VARIABLES just like any other OBJECT.

Metaclasses have INSTANCE METHODS which become SINGLETON METHODS when ATTACHED to an object (instance).

All CLASS METHODS (defined using self) are also stored in a metaclass.

The METACLASS is the FOUNDATION of METAprogramming.

METACLASSES can be extended in subclasses, effectively extending them with SINGLETON METHODS. And these SINGLETONS then use CLASS INSTANCE VARIABLES (defined in any class definition of the hierarchy) and run with them. No need for class variables.

This process also lets subclasses further DOWN the hierarchy inherit and override these METHODS and the instance variables they operate on. This again enables defining INSTANCE VARIABLES within a CLASS definition (class instance variables), to take the place of CLASS VARIABLES whose alteration would affect the entire inheritance hierarchy which invites nasty bugs.

So next time you see “class << self” you know that an SINGLETON METACLASS for the CURRENT INSTANCE (OBJECT) is created to extend it with (SINGLETON)CLASS METHODS.

Further reading:

http://continuousthinking.com/2006/11/17/ruby-class-variable-or-class-instance-variables

http://blog.thinkrelevance.com/2006/11/16/use-class-instance-variables-not-class-variables

And here for the architectural background: http://www.klankboomklang.com/2007/10/05/the-metaclass/

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Leave a Reply