meta-class subclass relationships

Discussion in 'Ruby' started by Greg Weeks, Nov 16, 2007.

  1. Greg Weeks

    Greg Weeks Guest

    Ruby exposes its singleton meta-classes, eg:

    class <<B ; $Meta_B = self ; end

    But their relationships are not quite what I expected. For example:

    Suppose that A inherits from B (and B inherits from Object). Of course,
    this means that A instances respond to all the B instance messages. So:

    A.new.is_a? B -> true

    At the same time, the A class object responds to all the B class object
    messages. So:

    class <<Object ; $Meta_Object = self ; end
    class <<B ; $Meta_B = self ; end
    class <<A ; $Meta_A = self ; end

    A.is_a? $Meta_A -> true
    B.is_a? $Meta_A -> false
    A.is_a? $Meta_B -> true
    B.is_a? $Meta_B -> true

    Since everything that is_a $Meta_A also is_a $Meta_B, I expected a
    subclass/superclass relationship. Indeed, I expected the following to
    be true:

    $Meta_A.superclass == $Meta_B
    $Meta_B.superclass == $Meta_Object
    $Meta_Object.superclass == Class
    Class.superclass == Module
    Module.superclass == Object
    Object.superclass == nil

    The above superclass chain reflects how a message to the class A object
    is looked up. What surprised me is that the first two equalities above
    are false.

    Should they have been true?

    FWIW: The superclass of both $Meta_A and $Meta_B is something called
    #<Class:Class>, which is its own superclass and is a subclass of
    $Meta_Object:

    $X = $Meta_A.superclass -> #<Class:Class>
    $X == $Meta_B.superclass -> true
    $X == $X.superclass -> true
    $X < $Meta_Object -> true
    --
    Posted via http://www.ruby-forum.com/.
     
    Greg Weeks, Nov 16, 2007
    #1
    1. Advertising

  2. Greg Weeks

    Greg Weeks Guest

    PS: I just realized that my (erroneous) expectation

    $Meta_A.superclass == $Meta_B
    $Meta_B.superclass == $Meta_Object

    is asserted in Figure 24.2 of the Pickaxe book (2nd edition). Eg, for
    the second equality, just replace "Guitar" with "B". So why, I wonder,
    isn't it true?
    --
    Posted via http://www.ruby-forum.com/.
     
    Greg Weeks, Nov 16, 2007
    #2
    1. Advertising

  3. Greg Weeks

    Robert Dober Guest

    Hmm seems consistent for me, although the model you expect should have
    some merits, I believe Smalltalk satisfies your expectations....
    However there are no metaclasses in ruby, only singleton classes,
    naming is important here to emphasis on the difference in behavior.

    635/135 > irb
    irb(main):001:0> a = Class::new
    => #<Class:0xb7d89750>
    irb(main):002:0> ma = class << a; self end
    => #<Class:#<Class:0xb7d89750>>
    irb(main):003:0> b = Class::new a
    => #<Class:0xb7d77500>
    irb(main):004:0> mb = class << b; self end
    => #<Class:#<Class:0xb7d77500>>
    irb(main):005:0> b < a
    => true
    irb(main):006:0> mb < ma
    => nil
    irb(main):007:0> mb.superclass
    => #<Class:Class>
    irb(main):008:0> ma.send :define_method, :a do 42 end
    => #<Proc:0xb7d56724@(irb):8>
    irb(main):009:0> ma.a
    NoMethodError: undefined method `a' for #<Class:#<Class:0xb7d89750>>
    from (irb):9
    from :0

    Stupid me, of course I defined a method for a

    irb(main):010:0> a.a
    => 42
    irb(main):011:0> b.a
    => 42
    which works for b too, as b < a

    irb(main):012:0> mma = class << ma; self end
    => #<Class:#<Class:#<Class:0xb7d89750>>>
    irb(main):013:0> mmb = class << mb; self end
    => #<Class:#<Class:#<Class:0xb7d77500>>>
    irb(main):014:0> mma.send :define_method, :ma do 42 end
    => #<Proc:0xb7d3e228@(irb):14>
    irb(main):015:0> ma.ma
    => 42
    Now this was for ma
    irb(main):016:0> mb.ma
    NoMethodError: undefined method `ma' for #<Class:#<Class:0xb7d77500>>
    from (irb):16
    from :0
    and as mb < ma does not hold this makes sense.

    BTW meta caught me I should have called the guys above sa, sb, ssa and ssb :(

    Interesting that the Pickaxe got this wrong, never publish code you
    have not run ;), or maybe this changed between 1.6 and 1.8?

    Cheers
    Robert



    --
    what do I think about Ruby?
    http://ruby-smalltalk.blogspot.com/
     
    Robert Dober, Nov 16, 2007
    #3
  4. Greg Weeks

    pluskid Guest

    On 11ÔÂ16ÈÕ, ÏÂÎç5ʱ20·Ö, Greg Weeks <greg.we...@arm..com> wrote:
    > FWIW: The superclass of both $Meta_A and $Meta_B is something called
    > #<Class:Class>, which is its own superclass and is a subclass of
    > $Meta_Object:
    >
    > $X = $Meta_A.superclass -> #<Class:Class>
    > $X == $Meta_B.superclass -> true
    > $X == $X.superclass -> true
    > $X < $Meta_Object -> true
    > --
    > Posted viahttp://www.ruby-forum.com/.


    In fact, currently in ruby:

    A.metaclass.superclass == A.class.metaclass

    if you define metaclass as :

    class Object
    def metaclass; class << self; self; end; end
    end

    That's why you see "$Meta_A.superclass -> #<Class:Class>". Maybe it
    is not very useful. But it is the case now. And here are some links if
    you are interested in:

    * http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html
    * http://practicalruby.blogspot.com/2007/02/ruby-metaprogramming-introduction.html
     
    pluskid, Nov 16, 2007
    #4
  5. Hi --

    On Fri, 16 Nov 2007, Greg Weeks wrote:

    > PS: I just realized that my (erroneous) expectation
    >
    > $Meta_A.superclass == $Meta_B
    > $Meta_B.superclass == $Meta_Object
    >
    > is asserted in Figure 24.2 of the Pickaxe book (2nd edition). Eg, for
    > the second equality, just replace "Guitar" with "B". So why, I wonder,
    > isn't it true?


    It will be :) It worked in 1.8.2, doesn't work in 1.8.6, works again
    in 1.9. I don't know what the rationale was for changing the model,
    but it's changed back.

    rubypal:~$ cat super.rb
    class Object
    def singleton_class
    class << self; self; end
    end
    end
    p String.singleton_class.superclass == Object.singleton_class

    rubypal:~$ /usr/local/lib/ruby-1.8.2/bin/ruby -v super.rb
    ruby 1.8.2 (2004-12-25) [i686-linux]
    true
    rubypal:~$ ruby -v super.rb
    ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-linux]
    false
    rubypal:~$ /usr/local/lib/ruby-svn/bin/ruby -v super.rb
    ruby 1.9.0 (2007-11-07 patchlevel 0) [i686-linux]
    true


    David

    --
    Upcoming training by David A. Black/Ruby Power and Light, LLC:
    * Advancing With Rails, Berlin, Germany, November 19-22
    * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details!
     
    David A. Black, Nov 16, 2007
    #5
  6. Hi --

    On Fri, 16 Nov 2007, Robert Dober wrote:

    > Interesting that the Pickaxe got this wrong, never publish code you
    > have not run ;), or maybe this changed between 1.6 and 1.8?


    It changed between 1.8.2 and 1.8.6 -- see my last response in this
    thread.


    David

    --
    Upcoming training by David A. Black/Ruby Power and Light, LLC:
    * Advancing With Rails, Berlin, Germany, November 19-22
    * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details!
     
    David A. Black, Nov 16, 2007
    #6
  7. On Nov 16, 12:32 pm, "David A. Black" <> wrote:
    > It will be :) It worked in 1.8.2, doesn't work in 1.8.6, works again
    > in 1.9. I don't know what the rationale was for changing the model,
    > but it's changed back.


    AFAIK, there is no rationale for it - it was a bug:
    http://rubyforge.org/tracker/?func=detail&atid=1698&aid=9462&group_id=426


    Paolo Perrotta
    Bologna, Italy
     
    Paolo \Nusco\ Perrotta, Nov 16, 2007
    #7
  8. On Nov 16, 2007 7:00 AM, Paolo Nusco Perrotta
    <> wrote:
    > On Nov 16, 12:32 pm, "David A. Black" <> wrote:
    > > It will be :) It worked in 1.8.2, doesn't work in 1.8.6, works again
    > > in 1.9. I don't know what the rationale was for changing the model,
    > > but it's changed back.

    >
    > AFAIK, there is no rationale for it - it was a bug:
    > http://rubyforge.org/tracker/?func=detail&atid=1698&aid=9462&group_id=426


    I notice that that bug is still marked as open.

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, Nov 16, 2007
    #8
  9. Greg Weeks

    Greg Weeks Guest

    *Many* thanks for the info. I was going to swallow the 1.8.6 behavior,
    but I much prefer the Figure 24.2 behavior.

    On the other hand, it is not true that A.class == $Meta_A. For the
    "class" message, the rule seems to be that you follow the inheritance
    chain until you find a non-virtual class. This would be a reasonable
    behavior for the "superclass" message too, I think. (Preferable,
    perhaps.)

    As for "Meta": I don't know if the English language is precise on this
    point. As I understand it, a meta-foo is a foo *about* foos. A
    meta-class is a class with class instances, I would think. Although
    most Ruby meta-classes are virtual, we can still mix modules into them,
    so they provide a powerful mechanism for meta-programming. That's why
    I'm inclined to call them (limited) meta-classes.
    --
    Posted via http://www.ruby-forum.com/.
     
    Greg Weeks, Nov 16, 2007
    #9
  10. Hi --

    On Sat, 17 Nov 2007, Greg Weeks wrote:

    > *Many* thanks for the info. I was going to swallow the 1.8.6 behavior,
    > but I much prefer the Figure 24.2 behavior.
    >
    > On the other hand, it is not true that A.class == $Meta_A. For the
    > "class" message, the rule seems to be that you follow the inheritance
    > chain until you find a non-virtual class. This would be a reasonable
    > behavior for the "superclass" message too, I think. (Preferable,
    > perhaps.)
    >
    > As for "Meta": I don't know if the English language is precise on this
    > point. As I understand it, a meta-foo is a foo *about* foos. A
    > meta-class is a class with class instances, I would think. Although
    > most Ruby meta-classes are virtual, we can still mix modules into them,
    > so they provide a powerful mechanism for meta-programming. That's why
    > I'm inclined to call them (limited) meta-classes.


    I believe Jim Weirich once said that the only real metaclass in Ruby
    is Class, since it's the source of class instances.


    David

    --
    Upcoming training by David A. Black/Ruby Power and Light, LLC:
    * Advancing With Rails, Berlin, Germany, November 19-22
    * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details!
     
    David A. Black, Nov 16, 2007
    #10
  11. Greg Weeks

    Greg Weeks Guest

    > I believe Jim Weirich once said that the only real metaclass in Ruby
    > is Class, since it's the source of class instances.


    True if "real" means "non-virtual", as it so often does. But that
    leaves
    virtual metaclasses, at the heart of Ruby metaprogramming.
    --
    Posted via http://www.ruby-forum.com/.
     
    Greg Weeks, Nov 16, 2007
    #11
  12. Hi --

    On Sat, 17 Nov 2007, Greg Weeks wrote:

    >> I believe Jim Weirich once said that the only real metaclass in Ruby
    >> is Class, since it's the source of class instances.

    >
    > True if "real" means "non-virtual", as it so often does. But that
    > leaves
    > virtual metaclasses, at the heart of Ruby metaprogramming.


    I'm not sure in what sense they're virtual (though I know that
    terminology occurs in some error messages). Once they're created, they
    exist as first-class objects.


    David

    --
    Upcoming training by David A. Black/Ruby Power and Light, LLC:
    * Advancing With Rails, Berlin, Germany, November 19-22
    * Intro to Rails, London, UK, December 3-6 (by Skills Matter)
    See http://www.rubypal.com for details!
     
    David A. Black, Nov 16, 2007
    #12
  13. On Nov 16, 2007 2:51 PM, David A. Black <> wrote:
    > Hi --
    >
    >
    > On Sat, 17 Nov 2007, Greg Weeks wrote:


    > > As for "Meta": I don't know if the English language is precise on this
    > > point. As I understand it, a meta-foo is a foo *about* foos. A
    > > meta-class is a class with class instances, I would think. Although
    > > most Ruby meta-classes are virtual, we can still mix modules into them,
    > > so they provide a powerful mechanism for meta-programming. That's why
    > > I'm inclined to call them (limited) meta-classes.

    >
    > I believe Jim Weirich once said that the only real metaclass in Ruby
    > is Class, since it's the source of class instances.


    In Smalltalk, where this stuff isn't so hidden. a metaclass is a class
    of a class.

    The main layout of classes and singleton classes as a parallel
    hierarchy with a cross-over and a loop at the top in Ruby is
    remarkably similar to that of Smalltalk. Of course Smalltalk also
    doesn't interpose module proxies as class-like things marked to be
    special, since it doesn't have modules.

    On the other hand Ruby doesn't have a Metaclass class like Smalltalk
    does. Smalltalk metaclasses have behavior mostly for interacting with
    the IDE. Sometimes I wish that Matz had put in a Metaclass class just
    so things wouldn't be so damned mysterious.

    IIRC the quote from Matz in the Pickaxe was that these things we are
    talking about "act just like" Smalltalk Metaclasses, but they aren't
    metaclasses, they are singleton classes of classes. I don't know if
    it's how Matz intended it, but I can interpret it as meaning that they
    aren't metaclasses just because there isn't a Metaclass class. In any
    event, I haven't found much interference from knowing how Smalltalk
    classes and metaclasses interact in understanding Ruby.

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, Nov 16, 2007
    #13
  14. Greg Weeks

    _why Guest

    On Sat, Nov 17, 2007 at 04:31:16AM +0900, Greg Weeks wrote:
    > As for "Meta": I don't know if the English language is precise on this
    > point. As I understand it, a meta-foo is a foo *about* foos. A
    > meta-class is a class with class instances, I would think. Although
    > most Ruby meta-classes are virtual, we can still mix modules into them,
    > so they provide a powerful mechanism for meta-programming. That's why
    > I'm inclined to call them (limited) meta-classes.


    Totally, I always think of meta- as meaning "once removed" in a
    parallel fashion more than a compound fashion, you know? Rather than
    strictly saying a "class about classes," I think it's also kind of
    a magnetic lasso around "classes informed about classes" or "an
    annex to a class."

    I guess metadata is straightforwardly "data about data," but data is
    a simple term. Class has complexities (definitions as well as
    storage space) which give ambiguity to the meta- part I think.

    Anyway, if you look at the use of the term on the web, like in
    naming sites, such as metafilter or metacritic: I don't think it is
    implied that these sites would be "filters about filters" or
    "critics criticizing other critics," but simply that they are once
    removed, culling information from other sites of a similar nature,
    operating in parallel rather than compoundly. I don't know, I'm
    just trying to give some other evidence of how elastic that little
    prefix can be.

    Maybe such things would be better suited with a super- but I like
    both English and Ruby for the ways you have a bit of... errr...
    poetic license, I guess.

    _why
     
    _why, Nov 16, 2007
    #14
  15. Greg Weeks

    Greg Weeks Guest

    >> True if "real" means "non-virtual", as it so often does. But that
    >> leaves
    >> virtual metaclasses, at the heart of Ruby metaprogramming.

    >
    > I'm not sure in what sense they're virtual (though I know that
    > terminology occurs in some error messages). Once they're created, they
    > exist as first-class objects.


    Right. But they can't be instantiated, and they are specially handled
    by various reflection methods (eg, #class completely ignores them). The
    term "virtual" didn't appeal to me much either, but Pickaxe and the
    error messages both use it.
    --
    Posted via http://www.ruby-forum.com/.
     
    Greg Weeks, Nov 16, 2007
    #15
  16. On Nov 16, 2007 5:27 PM, Greg Weeks <> wrote:
    > >> True if "real" means "non-virtual", as it so often does. But that
    > >> leaves
    > >> virtual metaclasses, at the heart of Ruby metaprogramming.

    > >
    > > I'm not sure in what sense they're virtual (though I know that
    > > terminology occurs in some error messages). Once they're created, they
    > > exist as first-class objects.

    >
    > Right. But they can't be instantiated,


    Well, actually they each have one instance, which is created at the
    same time they are (or vice-versa).

    This is the sense that they are 'singletons'.

    And I can think of at least three other classes which have single
    instances and can't be 'further' instantiated, although I've never
    heard NilClass, TrueClass, and FalseClass referred to as singleton
    classes.

    > and they are specially handled
    > by various reflection methods (eg, #class completely ignores them).


    And superclass seems unsure about them from release to release.

    >The
    > term "virtual" didn't appeal to me much either, but Pickaxe and the
    > error messages both use it.


    Right, as far as I can see it only comes up in the error messages when
    you try to subclass a class which has the FL_SINGLETON flag bit set.

    --
    Rick DeNatale

    My blog on Ruby
    http://talklikeaduck.denhaven2.com/
     
    Rick DeNatale, Nov 16, 2007
    #16
  17. Greg Weeks

    Guest

    On Sat, Nov 17, 2007 at 07:01:08AM +0900, _why wrote:
    > Maybe such things would be better suited with a super- but I like
    > both English and Ruby for the ways you have a bit of... errr...
    > poetic license, I guess.


    Meta is a prefix of Greek origin[1]. The Latin would be ``post'', which
    leads me to two thoughts.

    * A ruby metaclass really is like a postclass, which is pretty neat.

    * We're overusing prefixes like meta when so many options exist, such as
    postclass, or what about panclass, hypoclass, or epiclass[2]? I know,
    there's eigenclass, but does that really clarify it for anyone?

    Metaclass is already embedded in the culture, but I nonetheless
    find this to be a useful way to reason about the concept and how it fits
    into the language.


    [1] http://en.wikipedia.org/wiki/Meta
    [2] http://en.wikipedia.org/wiki/English_prefixes
     
    , Nov 16, 2007
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jstorta
    Replies:
    3
    Views:
    476
    jstorta
    Feb 20, 2006
  2. Nym Pseudo

    META NAME and META HTTP-EQUIV

    Nym Pseudo, Sep 26, 2003, in forum: HTML
    Replies:
    1
    Views:
    611
    =?iso-8859-1?Q?brucie?=
    Sep 26, 2003
  3. S.Volkov
    Replies:
    2
    Views:
    242
    S.Volkov
    Mar 12, 2006
  4. Trans
    Replies:
    8
    Views:
    353
    Robert Klemme
    Oct 23, 2008
  5. Fab

    Subclass of subclass

    Fab, Aug 9, 2012, in forum: C++
    Replies:
    0
    Views:
    417
Loading...

Share This Page