John Lam (CLR) wrote: > Thanks for sharing the eigenclass hack. > > More interestingly though, is where does the new method comes from when doing A.new. We believe that once we've looked at all of the ancestor classes' eigenclasses for new, that we then hit the Class and Module classes in the list of eigenclasses. Does that make sense as well? It's a bit strange because you start off looking through the eigenclass hierarchy for new, and then switch to the class hierarchy at the very end for Class, Module and Object. > > Is this how things are actually implemented? (BTW I'm not lazy here - we cannot look for ourselves). > > Also, as long as we respect this lookup mechanism, does anyone forsee any problems in merging the identities of the eigenclass and class objects into the same object (other folks who have code that explicitly depends on the behavior of the eigenclass hack -- not sure what this really means at this time though). Don't get confused now...class methods are not defined on the "eigenclass", they're instance methods on the class object. The class object is often also referred to as the object's metaclass, though this terminology can be confusing. So if you're calling Array.new, it's looking at the Array class object to call one of its instance methods...which are in turn located in a dictionary on Array's metaclass. Now I believe you could simply have two dictionaries on Array and you would support the appropriate lookup semantics for class vs instance methods. But would you be able to support all the following scenarios? class << Array; def foo; "hello"; end; end; Array.hello => "hello" def Array.foo; "hello"; end; Array.hello => "foo" class Array class << self def foo "hello" end end def self.bar "goodbye" end end Array.foo => "hello" Array.bar => "goodbye" This is just a sampling of metaclass weirdness...when you get into Class.new(...) tricks and marshalling, it gets more complicated. And trust me, you *do* need to support all of them if you want nontrivial apps to run. - Charlie