On 12/10/06, Trans <transfire / gmail.com> wrote:
> George Ogata wrote:
> > 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.

Hmm, looks like a small combinatorial explosion.  :-(

> 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.

That's what I was kinda hoping to avoid--special cases.  Some crazy
hacker's gonna be building the arg list programmatically one day, and
find they have to treat the empty list specially.  I suppose you could
do something like:

  def methods(visibilities=[:public, :protected], restriction=nil)
    ...
  end

Or maaaybe:

  def methods(*args)
    if !args.empty? && args.all?{|a| a.respond_to?(:to_sym)}
      visibilities = args.map{|a| a.to_sym}
      restriction  = nil
    else
      visibilities, restriction = *args
      visibilities ||= [:public, :protected]
    end
    ...
  end

...where restriction would be things like :singleton and
:singleton_with_modules (or something--"ancestors" is too generic
IMHO; it strictly means just the modules included in the singleton
class, and nothing more), or nil for the whole ancestor chain.

But OTOH, it's starting to look a little scary now.  Maybe I just need
time to let it sink in.

> 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? }

Conceptually pleasing maybe, though quite verbose if all you want are
names.  :-/