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

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?

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@:8(irb)
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@:14(irb)
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 :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

Hi –

On Fri, 16 Nov 2007, pluskid wrote:

Posted viahttp://www.ruby-forum.com/.

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:

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 11ÔÂ16ÈÕ, ÏÂÎç5ʱ20·Ö, Greg W. [email protected] 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://practicalruby.blogspot.com/2007/02/ruby-metaprogramming-introduction.html

Hi –

On Fri, 16 Nov 2007, Robert D. 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

On Nov 16, 12:32 pm, “David A. Black” [email protected] 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

Paolo Perrotta
Bologna, Italy

Hi –

On Fri, 16 Nov 2007, Greg W. 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 :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

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.

On Nov 16, 2007 7:00 AM, Paolo Nusco P.
[email protected] wrote:

On Nov 16, 12:32 pm, “David A. Black” [email protected] 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

I notice that that bug is still marked as open.


Rick DeNatale

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

Hi –

On Sat, 17 Nov 2007, Greg W. wrote:

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 W. once said that the only real metaclass in Ruby
is Class, since it’s the source of class instances.

David

I believe Jim W. 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.

Hi –

On Sat, 17 Nov 2007, Greg W. wrote:

I believe Jim W. 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

On Nov 16, 2007 2:51 PM, David A. Black [email protected] wrote:

Hi –

On Sat, 17 Nov 2007, Greg W. 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 W. 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/

On Sat, Nov 17, 2007 at 04:31:16AM +0900, Greg W. 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

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.

On Nov 16, 2007 5:27 PM, Greg W. [email protected] 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/

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

On Nov 16, 2007 6:47 PM, [email protected] wrote:

  • 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

Excerpting from that article:

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/