Hi -- On Mon, 4 Apr 2005, Johan Holmberg wrote: > > Hi! > > I was trying to find out the "class methods" of some classes. > Looking in the PickAxe I found out that there are at least three methods that > return almost the same thing for a class/module: > > Object#singleton_methods(flag) > Object#public_methods(flag) > Object#methods(flag) > > So potentially we can get six (3 * 2) different results. To find out the > difference between all invocations, I ran the methods on all builitin > classes/modules, and compared the result. It turned out that I actually got 4 > different results: > > - methods(false) and singleton_methods(false) > give the same result > > - singleton_methods(true) > gives a unique result > > - public_methods(false) > gives a unique result > > - methods(true) and public_methods(true) > give the same result > > The PickAxe said that Object#public_methods was a synonym for Object#methods. > This is apparently not true (or true only when the argument is "true"). > > To me it seem like these methods have "degenerated" into something that is > almost impossible to explain. Neither the PickAxe nor the online-docs > explains it in a way so I can understand the differences. Can anyone explain > the logic behind these different methods and their results? I can offer one observation that might account for some of this: "singleton_methods(true)" means "singleton methods on this object or, if the object is a Class, this object and its ancestral classes." For example: irb(main):001:0> class A; def A.x; end; end; class B < A; end => nil irb(main):002:0> B.singleton_methods(false) => [] irb(main):003:0> B.singleton_methods(true) => ["x"] I would argue that there is a bit of a contradiction here, arising from the special case of inheritance. x is not really a singleton method of B; it's a singleton method of B's superclass, and the rules of inheritance allow the (arguably anomalous) behavior that the subclass can serve as the receiver for what would otherwise be a truly singleton method. I believe this is the only scenario where, after doing this: def obj.meth; end any object other than obj can call meth. In other words, a Class's singleton methods ("class methods") don't quite behave in a singleton fashion. These true/false flags are awfully opaque, so B.singleton_methods(true) still sounds like it should be B's singleton methods, not those of B and other object(s). Aside from the length of the method name, it should be something like: B.singleton_and_inherited_singleton_methods to acknowledge that B is in the unusual position of being able to handle calls to the singleton methods of certain other objects. Or -- B.class_methods. I really like the fact that class methods in Ruby are just an application of the more general singleton-method principle. But if they are in fact different at the language level, it might be best to label them. David -- David A. Black dblack / wobblini.net