From: 7stud -- Date: 2011-08-23T10:46:03+09:00 Subject: Re: Gritty Details of super() luke gruber wrote in post #1017884: >> The question is: Why isn't M's singleton class inserted into the >> singleton class hierarchy? >> >> As to why that is? I have no idea. Things would be nice and >> symmetrical if a module's singleton class did get inserted in the >> singleton class hierarchy. >> >> (The method lookup diagrams were copied from Metaprogramming Ruby.) > >>7stud > > Thanks 7stud, that was exactly what I was trying to get at. > The confusion I have with the current approach is this: > > If Ruby wanted us to forget about the whole anonymous superclass > proxying the module on inclusion or extension, then in order for the > module (which, in our mental makeup in this case is right above the > class that included/extended the module), it would make the most sense > for singleton methods called on our class to resolve/lookup the module's > singleton methods upon a method_missing or super or whatever. > > However, this is not the case as we all know. > > So OK, maybe Ruby wants us to KNOW about the anonymous superclass that > is proxying the module, and for this to not only be an implementation > feature/hack, but a feature of the language that we can put in our > mental model of method lookup. But if we put this in our mental model, > then a couple of problems arise for me. > > First, ::ancestors. ::ancestors shows the module name, which is nice, > but crumples our mental model a bit as it should show the anon > superclass if our mental model was changed. I don't think changing the name 'M' to 'anon-M', or even worse: "", would make much difference. You just have to know that superclass() doesn't return included modules, and ancestors does. > The second > problem/misunderstanding for me is that the anonymous superclass that > proxies the module (ASCTPTM...hehe) > does not proxy the singleton methods of the module. > I think you aren't making the correct distinction here: there are two classes not one. When you include a module, ruby creates an anonymous class containing the module's instance methods, which are defined like this: module M def eat puts 'munch, munch' end end ...and ruby also creates a singleton class containing the module's singleton methods, which are defined like this: module M M.greet puts 'MMMM' end end In all situations in ruby, the singleton methods are not in the same class as the instance methods. For instance, if you do this: class Dog def Dog.greet puts 'hello' end def speak puts 'woof, woof' end end That doesn't create just one class. ruby creates two classes: Dog and #Dog, which are in two different lookup hierarchies--as the lookup diagram shows. Therefore, your statement here: > the anonymous superclass that > proxies the module (ASCTPTM...hehe) > does not proxy the singleton methods of the module. is non-sensical because a regular class (or an anonymous class) never contains the singleton methods. This stuff isn't easy to understand, but you can make some sense of things. However, I find the following totally unhelpful: > Care must be taken not to confuse inheritance hierarchies: there are > two of them as 7stud has shown with the ASCII graphic. Including a > module in a class inserts it into its chain of ancestors, but has no > effect on the inheritance hierarchy of the class's singleton class: > > Basic class: > > irb(main):001:0> class C;end > => nil > irb(main):002:0> C.ancestors > => [C, Object, Kernel, BasicObject] > irb(main):003:0> sc = class < => # > irb(main):004:0> sc.ancestors > => [Class, Module, Object, Kernel, BasicObject] > Note that sc.ancestors does not list any of the singleton classes as detailed in the lookup diagram. > With module included: > > irb(main):005:0> module M;end > => nil > irb(main):006:0> class C;include M;end > => C > irb(main):007:0> C.ancestors > => [C, M, Object, Kernel, BasicObject] > irb(main):008:0> sc.ancestors > => [Class, Module, Object, Kernel, BasicObject] So how does that result prove that including a module does nothing to the lookup diagram? sc.ancestors never listed the singleton classes in the first place, and after including the module sc.ancestors still doesn't list the singleton classes. -- Posted via http://www.ruby-forum.com/.