Hi --

On Wed, 30 Aug 2006, Rick DeNatale wrote:

> If a singleton class is a class which is tied to one and only  one
> object, then a singleton method should be a method tied to one and
> only one object as well, but check this out:
>
>  class X
>       def foo;end
>  end
>
>  X.singleton_methods => ["foo"]
>
>  class Y < X; end
>
>  Y.singleton_methods => ["foo"]
>
> Does anyone beside me find that surprising?

It's always struck me as an anomaly.  It's redeemed somewhat by the
superclass thing, whereby class << X is the superclass of class << Y.
(At least, in 1.8.2 and > 1.8.5 it is; I'm not sure why that got
derailed by 1.8.4, since it still behaves that way.)

> Now the rdoc of Object#singleton_methods says that it takes an
> optional boolean argument which if false will include methods in
> modules included in obj.
>
>  Y.singleton_methods(false) => []
>
> So does Y include X?
>
>  Y.include? X
>  TypeError: wrong argument type Class (expected Module)
>       from (irb):29:in `include?'
>       from (irb):29

I'm not sure what you're getting at here.  Are you thinking of whether
Y's ancestors include X?

> So the operational definition of a singleton methods seems to be a
> method of an object which appears in a singleton class or a module
> mixed directly INTO a singleton class, or comes from a singleton class
> which is in the superclass chain of the objects class BEFORE a non
> singleton class, or a module directly mixed into one of those
> singleton classes.  Whew.

It's not too hard if you draw it :-)  It's basically just a bunch of
classes and modules, with the object walking through them looking for
a method.

[...]

> It appears that a lot of the reason for FL_SINGLETON and T_ICLASS is
> to hide a slightly tricky implementation from showing through some of
> the reflection methods.  Perhaps Ruby would be a little cleaner if it
> just called a metaclass a metaclass, and a singleton class a singleton
> class, and reserved the later for a class providing behavior for a
> single instance.  But that's just my opinion and it's not the way
> things are.

I tend to call the singleton classes of classes singleton classes (did
you follow that? :-) in part because the term "metaclass" doesn't do
much for me.  But the singleton-ness of them is definitely in
question.

> I just realized that there's no class_methods family of methods in
> Ruby.  I can't say:
>
>  Array.class_methods
>
> instead I have to say:
>  Array.singleton_methods

Now that's the cool part :-)  I love the fact that there's no
language-level notion of a "class method".  In general, Ruby has this
way of providing a remarkably featureless (I use the word advisedly)
landscape, out of the featurelessness of which one can mold features.
So if you feel like there should be class methods, you can tap into
the fact that class objects can have singleton(ish) methods.  But as
far as Ruby is concerned, there's no special case.

Frequently, the special cases and constructs in Ruby are in the eye of
the beholder, so to speak.  I put "attributes" in that category too,
even though the presence of the attr_* methods makes that a somewhat
more language-supported thing.

It's also why I dislike class variables so much.  They're a
language-level feature that I think can be done better using a blend
of other features.

> While I can say
>  Array.private_instance_methods
>
> How do I get the private_class_methods?

class << Array; private_instance_methods(false); end

or something along those lines.


David

-- 
                   David A. Black | dblack / wobblini.net
Author of "Ruby for Rails"   [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog)        [2] | Co-director, Ruby Central, Inc.   [4]
[1] http://www.manning.com/black | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com    | [4] http://www.rubycentral.org