From: Trans Date: 2006-12-10T07:42:18+09:00 Subject: Re: #method(false) returns singleton methods? George Ogata wrote: > On 12/1/06, Trans wrote: > > > > > On 11/30/06, Trans wrote: > > Thanks. I suppose matz has his reasons. Though I can't say I quite > > phatom them. Even his changelog entry isn;t exactly corrent since only > > _public_ singleton methods show up if argument is false; and list all > > _public_ methods otherwise. > > Almost right; it's actually _nonprivate_ methods. ;-) And yeah, > there's a peculiar asymmetry, between #methods and > #(public|protected|private)_methods in exactly what gets included, > even with the same argument. For example, #methods(false) only hits > the singleton class, but #public_methods(false) goes up the ancestor > chain to and including #class . In fact, #methods(false) is actually > equivalent to #singleton_methods(false), yet another #*_method method > with different boolean-parameter semantics. :-/ > > class B > def boo > end > end > > class D < B > def doo > end > end > > d = D.new > > module M > def moo > end > end > > class << d > include M > def scoo > end > end > > # so ancestor chain is: # < M < D < B > > d.methods.grep(/oo/) #=> ["boo", "scoo", "doo", "moo"] > d.methods(false).grep(/oo/) #=> ["scoo"] > d.public_methods.grep(/oo/) #=> ["boo", "scoo", "doo", "moo"] > d.public_methods(false).grep(/oo/) #=> ["doo", "scoo", "moo"] > d.singleton_methods.grep(/oo/) #=> ["scoo", "moo"] > d.singleton_methods(false).grep(/oo/) #=> ["scoo"] > > > I have to agree with David Black that this true false parameter has no > > sematic quality. That is differs in result from obj.methods to > > class.methods is further confusing on top of the distinctions between > > methods, public_methods, etc. This was brought up a long time ago, but > > I still agress with the idea of a sinlge interface that takes symbolic > > "filters". > > > > obj.methods(:singleton) > > obj.methods(:public) > > obj.methods(:all) > > obj.methods(:private, :public) # combination > > > > etc. > > I agree that the boolean parameter is not ideal. I'm not entirely > sold on your suggestion yet either, though. Firstly, I'm not so sure > :singleton belongs in there. I'd expect (:singleton, :public) to mean > "singleton AND public", whereas (:public, :private) looks more like > "public OR private", and mushing 'em all up feels a bit icky. This > still doesn't cover the current semantics of #singleton_methods(true), > either. Would we need another filter to mean "singleton with included > modules"? > > The other bit of irkage I forsee with this is that presumably no args > would mean return [], which means you'd lose the convenience of > querying things usefully with plain old "thing.methods". Good point about singleton, I suppose the easiest adjustment would be :singleton_public, :singleton_private, :singleton_protected and :singleton_all. Where :singleton itself could just be a synonym for :singleton_public. Given how things currently work if no symbol is given at all it would be the same as if just :public were given. That would help a little with backwords compatability. Howerver there's still the question of ancestor inclusion --and I suppose just adding :ancestors would be enough for that. Aside, it would be rather interesting if methods could be handled 1st class. Then: obj.methods.select{ |m| m.singleton? } obj.methods.select{ |m| m.public? or m.private? } obj.methods.select{ |m| m.inherited? } > Well, I'd hardly label myself a "doc specialist", but if you won't, I > will. After all, what code could be more worth documenting than the > ruby core? ;-) Do that and you will be! ;-) As for me, I just mean I don't have the time. t.