I was under the impression that obj.method
caused ruby to look for method
thusly:
- Look in
obj
's singleton class. - Look in the modules included by
obj
's singleton class. - Look in
obj
's class. - Look in the modules included by
obj
's class - repeat steps 3 and 4 on the class's superclass until found
- If never found, call
method_missing
on the original object,obj
.
Under this model, the only singleton class searched for the method is the singleton class of the original receiver, obj
. However, this model can't explain the fact that a subclass can access its superclass's singleton methods. For example
class Foo
def self.foo
"foo"
end
end
class Bar < Foo
end
Bar.foo #=> "foo"
I'm confused because I believe this means that Foo
's singleton class is at some point searched for the method foo
. However, under the model above, I would expect that only Bar
's singleton class would be searched for foo
. Failing that, I would expect ruby to look in Bar
's class, Class
, and then continue crawling up the superclass chain (skipping Foo
and its singleton class completely).
So my question: what is missing from my understanding of Ruby method lookup which explains the fact that a class can access its superclass's singleton methods?
When subclassing, not only is
Bar.superclass
set toFoo
, but the same holds true for the singleton classes:So you're not really confused. The actual lookup is:
obj
's singleton class.method_missing
It's pretty straightforward. Or not really, but anyhow:
Where "metaclass" is really "singleton class". What's missing in your model is
Bar.superclass
inheritsFoo.superclass
. Plain and simple :)