From: why the lucky stiff Date: 2005-04-19T02:21:06+09:00 Subject: Re: [ANN] Article: Seeing Metaclasses Clearly Jeffrey Moss wrote: > Being somewhat new to the concept of metaprogramming, I can tell you > what is particularly confusing is the use of class << self, how this > is like the root of all singleton behavior, how it differs from class > a < b (perhaps even display how it works inside the interpreter). I > wasn't sure what the difference between the < and the << operator was, > so I had to go look it up. My article briefly discusses the singleton class notation (the << you are referring to). This notation is very simple to understand once you've gotten the hang of: 1. Objects are containers for instance variables. 2. Classes are containers for methods and instance variables. There are more to objects and classes than this, but for the sake of this discussion, it's useful to whittle it down to this. a = Object.new a.instance_variable_set( "@name", "Jeff" ) I've created a new object above, storage for instance variables. I've added an instance variable to the object. In doing so, I called the `instance_variable_set' method. This method isn't contained in the `a' object. It's contained way up the inheritance tree, in the Object class. Again: the instance variables are stored in the object. The methods are stored in a class up the inheritance tree. class << a def name; @name; end end We're opening a metaclass here. What is a metaclass? It's method storage for an object. An object can only store instance variables. The `name' method has been added to the metaclass (the personal method storage) for the object `a'. The most needlessly confusing construct in Ruby is `class << self'. You're simply accessing the method storage for whatever object is currently `self'. class Dragon class << self; p self; end end Prints: # Okay, so we're in the metaclass for a class. But what is that? It's method storage for class methods. Normal instance methods are stored directly in the class. But class methods are stored in the metaclass. class Dragon def self.me; p self; end # This method is stored in the metaclass def me; p self; end # This method is stored in the class end Dragon.me #=> Dragon Dragon.new.me #=> # Everyone who uses class methods uses metaclasses. class << Dragon def roar; "#"; end end Dragon.roar #=> # d = Dragon.new class << d def roar; "#"; end end d.roar #=> # I don't really get into this in the article, since I've opted to use the `metaclass' method and `meta_eval' which are alternate forms of the above. The < operator is a completely different operator, used strictly for setting the superclass of a class. But one handy thing about metaclass (which I believe qualifies them for the meta- prefix) is that they follow the inheritance tree, simply remaining one level removed. >> Dragon.metaclass => # >> Dragon.metaclass.superclass => # >> Dragon.superclass.metaclass => # See, an object's metaclass' superclass is the same as the object's superclass' metaclass. > Also the difference between class instance variables and class > variables could use some extra explaining, it seems you're just saying > what to do and what not to do, but not why you can't or shouldn't do > it, and why a @@ class variable is handy. I'll address this once I'm sure I completely understand variable.c and have played around with class variables in metaclasses a bit more. _why