I've missed the memo somewhere, and I hope you'll explain this to me.
Why is the eigenclass of an object different from self.class
?
class Foo
def initialize(symbol)
eigenclass = class << self
self
end
eigenclass.class_eval do
attr_accessor symbol
end
end
end
My train of logic that equates the eigenclass with class.self
is rather simple:
class << self
is a way of declaring class methods, rather than instance methods. It's a shortcut to def Foo.bar
.
So within the reference to the class object, returning self
should be identical to self.class
. This is because class << self
would set self
to Foo.class
for definition of class methods/attributes.
Am I just confused? Or, is this a sneaky trick of Ruby meta-programming?
class << self
is more than just a way of declaring class methods (though it can be used that way). Probably you've seen some usage like:This works, and is equivalent to
def Foo.a
, but the way it works is a little subtle. The secret is thatself
, in that context, refers to the objectFoo
, whose class is a unique, anonymous subclass ofClass
. This subclass is calledFoo
's eigenclass. Sodef a
creates a new method calleda
inFoo
's eigenclass, accessible by the normal method call syntax:Foo.a
.Now let's look at a different example:
This example is the same as the last one, though it may be hard to tell at first.
frob
is defined, not on theString
class, but on the eigenclass ofstr
, a unique anonymous subclass ofString
. Sostr
has afrob
method, but instances ofString
in general do not. We could also have overridden methods of String (very useful in certain tricky testing scenarios).Now we're equipped to understand your original example. Inside
Foo
's initialize method,self
refers not to the classFoo
, but to some particular instance ofFoo
. Its eigenclass is a subclass ofFoo
, but it is notFoo
; it couldn't be, or else the trick we saw in the second example couldn't work. So to continue your example: