Meta-class subclass relationships

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

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

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

···

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

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

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
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 :frowning:

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

···

from :0
        from :0

--
what do I think about Ruby?
http://ruby-smalltalk.blogspot.com/

Hi --

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

The superclass relationship between singleton classes is actually
useful -- it allows subclasses to call the singleton methods of their
superclasses. (Which means that "singleton" is probably in some doubt
as the best term in this case :slight_smile: I'm not sold on "meta", though.)

Strictly speaking, this ability can be implemented with or without the
superclass model; in fact, some recent Ruby versions will report false
if you test for superclass-ness in these cases. But it's been
restored, and it makes a lot of sense as a way of fitting this
otherwise kind of anomalous piece into the puzzle.

David

···

On Fri, 16 Nov 2007, pluskid wrote:

On 11ÔÂ16ÈÕ, ÏÂÎç5ʱ20·Ö, Greg Weeks <greg.we...@arm.com> wrote:

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

Hi --

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 :slight_smile: 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

···

On Fri, 16 Nov 2007, Greg Weeks wrote:

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

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!

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

···

On Nov 16, 12:32 pm, "David A. Black" <dbl...@rubypal.com> wrote:

It will be :slight_smile: 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.

I notice that that bug is still marked as open.

···

On Nov 16, 2007 7:00 AM, Paolo Nusco Perrotta <paolo.nusco.perrotta@gmail.com> wrote:

On Nov 16, 12:32 pm, "David A. Black" <dbl...@rubypal.com> wrote:
> It will be :slight_smile: 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

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

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

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!

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

···

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.

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

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.

···

On Nov 16, 2007 2:51 PM, David A. Black <dblack@rubypal.com> 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.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

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] Meta - Wikipedia
[2] English prefix - Wikipedia

···

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.

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!

Excerpting from that article:

···

On Nov 16, 2007 6:47 PM, <ruby-talk@metacall.org> wrote:

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] Meta - Wikipedia

=======
In epistemology, the prefix meta- is used to mean about (its own
category). For example, metadata are data about data (who has produced
them, when, what format the data are in and so on). Similarly,
metamemory in psychology means an individual's knowledge about whether
or not they would remember something if they concentrated on recalling
it. Furthermore, metaemotion in psychology means an individual's
emotion about his/her own basic emotion, or somebody else's basic
emotion

...

Etymology

The prefix is derived by back-formation from the Greek preposition and
prefix meta- (μετά) which meant either "after", "beside" or "with".
Meta- & Meso- are thought to have come into Greek together from a
mutual cognate, which would further imply 'meta' to contain or be of
the meaning "parallel". [1]

Quine and Hofstadter

The OED cites uses of the meta- prefix as "beyond, about" (such as
meta-economics and meta-philosophy) going back to 1917. However, these
formations are directly parallel to the original "metaphysics" and
"metaphysical", that is, as a prefix to general nouns (fields of
study) or adjectives. Going by the OED citations, it began to be used
with specific nouns in connection with mathematical logic sometime
before 1929. (In 1920 David Hilbert proposed a research project in
what was called "metamathematics.")

A notable early citation is Quine's 1937 use of the word
"metatheorem", where meta- clearly has the modern meaning of "an X
about X". (Note that earlier uses of "meta-economics" and even
"metaphysics" do not have this doubled conceptual structure, they are
about or beyond X but they do not themselves constitute an X). Note
also that this modern meaning allows for self-reference, since if
something is about the category to which it belongs, it can be about
itself; it is therefore no coincidence that we find Quine, a
mathemetician interested in self-reference, using it.

Douglas Hofstadter, in his 1979 book Gödel, Escher, Bach (and in the
sequel, Metamagical Themas), popularized this meaning of the term.
This book, which deals extensively with self-reference and touches on
Quine and his work, was influential in many computer-related
subcultures, and is probably largely responsible for the popularity of
the prefix, for its use as a solo term, and for the many recent
coinages which use it. Hofstadter uses the meta as a stand-alone word,
both as an adjective and as a directional preposition ("going meta", a
term he coins for the old rhetorical trick of taking a debate or
analysis to another level of abstraction, as in "This debate isn't
going anywhere."). This book is also probably responsible for the
direct association of "meta" with self-reference, as opposed to just
abstraction. The sentence "This sentence contains thirty six letters."
along with the sentence it is embedded in are examples of sentences
that reference themselves in this way.

This is the sense of meta in metaclass. First it was adopted from the
greek meta. Although the Greek meta and Latin post might have some
meanings in common. I've got a hard time understanding how postclass
would mean anything like metaclass. and postmemory for metamemory,
postemotion for metaemotion and postdata for metadata just don't ring
true.

The reference to Hoftstadter's GEB and it's publication date of 1979
is interesting. I can't remember exactly when in the evolution of
Smalltalk the term metaclass was born, but it was definitely there in
the 1980 version.

It just so happens that I pulled my old copy of GEB down from the
attic a week or so ago. Rereading it has been competing for my
reading time with "SQL for MySQL Developers." An interesting note is
that back then a 777 page textbook sold for $17.50 back then!

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

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

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

···

On Nov 16, 2007 5:27 PM, Greg Weeks <greg.weeks@arm.com> wrote:

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/