From: Saynatkari Date: 2005-04-04T06:56:18+09:00 Subject: Re: signleton_methods / methods / public_methods - weirdness? David A. Black wrote: > 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. other = obj.clone > 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 E