[ANN] Article: Seeing Metaclasses Clearly

  • Thread starter why the lucky stiff
  • Start date
D

David A. Black

Hi --

Sure, I'm aware that "virtual class" is the generic term, while Matz has also
used "singleton class" and "meta-object" to describe these classes used in
tandem with an RObject.

I only use the term "metaclass" because it is the term predominantly used in
the PickAxe II. While Dave does interchangibly use "virtual class" and
"singleton class", the only term he uses to generically refer to the
construct is "metaclass".

And I really need to be able to wrap these up in a single word, whilst still
jiving with the PickAxe.

I read the Pickaxe differently, especially the box on p. 382. It
paraphrases Matz as having said: "You can call it _metaclass_ but,
unlike Smalltalk, it's not a class of a class; it's a singleton class
of a class."

I don't think there's any case where Dave refers to a singleton class
as a metaclass, except where the object is a Class, but I could be
wrong about that... ?

Anyway, when RCR 231 gets addressed, we'll find out for sure :)

(I think I misread the p. 382 thing about "virtual". It does actually
sound like Matz is accepting it as a synonym for "singleton", though I
avoid it because I don't see anything "virtual" about singleton
classes. They're objects.)


David
 
D

David A. Black

--927295978-337954697-1113854452=:31436
Content-Type: MULTIPART/MIXED; BOUNDARY="927295978-337954697-1113854452=:31436"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

--927295978-337954697-1113854452=:31436
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

Nice article, but I disagree in the point that @@vars are simpler than= =20
class instance variables. Class instance variables have odd semantics in= =20
the current Ruby which means that they will probably do some detail=20
different than you expect.

But you have to do:

class Foo
=09@var1 =3D []
=09@var2 =3D {}
=09class << self
=09=09attr_accessor :var1, :var2
=09end
end

to get reasonable access to those class instance variables inside an inst= ance=20
method, and even then you have to do self.class.var1


Once you 'get it' it's not TERRIBLY difficult, but I would say that the a= bove=20
is more than enough justification for calling @@foo simpler. Simpler, but= =20
also confusing in the inherited-class cases.

Also, they're different. In 2.0, it sounds like they will be more
similar to each other, because class vars will be truly scoped per
class. I'm not in favor of that. Class variables, in my view, are
responsible already for a huge amount of misunderstanding of
*instance* variables (because the @/@@ thing always makes people think
there must be some connection or similarity between the two entities,
and then they get confused when there isn't).

I'm not sure what the best thing would be. I tend to root for the
removal of class variables entirely. I might even be able to tolerate
#class_attr_* methods, which actually make no sense (since there's
really no more reason to create special methods, in that area, for
Class objects than any other object) but might keep things smoother.


David

--=20
David A. Black
(e-mail address removed)
--927295978-337954697-1113854452=:31436--
--927295978-337954697-1113854452=:31436--
 
L

Lionel Thiry

Florian Groß a écrit :
Oh, that's already done by Module#define_method then. Perhaps you can
just make that method public?

def class_def name, &blk
class_eval { self.define_method name, &blk }
end

It was the other solution I thought for.
 
J

Jim Weirich

[Regarding the term "metaclass"]
I read the Pickaxe differently, especially the box on p. 382. It
paraphrases Matz as having said: "You can call it _metaclass_ but,
unlike Smalltalk, it's not a class of a class; it's a singleton class
of a class."

I don't have the pickaxe with me (its at work), but let me quote from "Putting
Metaclasses to Work" by Ira R. Forman and Scott H. Danforth. The quote is
longish, but useful in understanding metaclasses. From the Preface:
"If one thinks of objects as cookies, then classes are analogous to cookie
cutters. Cookie cutters are teamplates that are used to make and determine
the properties of cookies; classes make and determine the properties of
objects. But ow are cookie cutters themselvfes made? Let us ssay that they
are pressed from sheet metal using a cookie cutter press (a piece of heavy
machinery). So, if a cookie cutter press is ed to make cookie cutters, what
is used to make classes? The answer is a metaclass."

So, the instances of a metaclass are classes. Ruby happens to implement
metaclasses as singleton classes (or virtual classes, whatever). So the
singleton class of a class is a metaclass, but the singleton class of
something that is not a class, would not be a meta class.

I would modify Why's metaid library thusly:

class Object
def singletonclass
class << self
self
end
end
end
class Class
def metaclass
singletonclass
end
end

Allowing ...
=> true
(I think I misread the p. 382 thing about "virtual". It does actually
sound like Matz is accepting it as a synonym for "singleton", though I
avoid it because I don't see anything "virtual" about singleton
classes. They're objects.)

I think the "virtual" is a modifier of "class", not "object". A virtual class
is something that is like a class in someways (it holds instance methods),
but unlike a class in other ways (can't create new instances of it).
 
M

Martin DeMello

Jim Weirich said:
So, the instances of a metaclass are classes. Ruby happens to implement
metaclasses as singleton classes (or virtual classes, whatever). So the
singleton class of a class is a metaclass, but the singleton class of
something that is not a class, would not be a meta class.

I would modify Why's metaid library thusly:

class Object
def singletonclass
class << self
self
end
end
end
class Class
def metaclass
singletonclass
end
end

+1 - in fact, I think that should go into the FAQ, under "What is the
difference between a singleton class and a metaclass?"

martin
 
T

ts

J> So, the instances of a metaclass are classes. Ruby happens to implement
J> metaclasses as singleton classes (or virtual classes, whatever). So the
J> singleton class of a class is a metaclass, but the singleton class of
J> something that is not a class, would not be a meta class.

A singleton class never create an instance, in ruby.

Don't make confusion with another language, which use

"Putting Metaclasses to Work: A New Dimension in Object-Oriented
Programming"

as references.



Guy Decoux
 
D

David A. Black

Hi --

I think the "virtual" is a modifier of "class", not "object". A virtual class
is something that is like a class in someways (it holds instance methods),
but unlike a class in other ways (can't create new instances of it).

It is a modifier of "class", not "object"; I think Matz (via Pickaxe)
is saying that "virtual class" is an acceptable synonym for "singleton
class". Actually I don't like it both for my reason ("virtual", taken
on its own, doesn't evoke something as concrete as a singleton class)
and for your reason (it has a meaning in other languages that is only
a partial fit, as I understand it, for Ruby's singleton classes).


David
 
D

David A. Black

Hi --

I don't have the pickaxe with me (its at work), but let me quote from "Putting
Metaclasses to Work" by Ira R. Forman and Scott H. Danforth. The quote is
longish, but useful in understanding metaclasses. From the Preface:


So, the instances of a metaclass are classes. Ruby happens to implement
metaclasses as singleton classes (or virtual classes, whatever). So the
singleton class of a class is a metaclass, but the singleton class of
something that is not a class, would not be a meta class.

I have some trouble applying the quotation to Ruby, since classes make
but don't determine the properties of objects, and also -- even more
-- because that description of a metaclass sounds more like class
Class than like singleton classes of classes (since class Class is the
only thing in Ruby from which arbitrarily many Class objects can be
"pressed"). So it doesn't really seem like singleton classes of
classes are accounted for in the quotation.

(I will try to consolidate my comments next time and not respond three
times in a row :)


David
 
J

Jim Weirich

David A. Black said:
I have some trouble applying the quotation to Ruby, since classes make
but don't determine the properties of objects,

I think you misunderstand "properties". It is true that the class does
not (directly) influence the attributes/instance variables of an object.
But properties also include the methods of the object, which are directly
influenced by the class.

Actually, the objections regarding "making objects" and "instance variable
properties" goes more to saying that the singleton classes of classes are
not /classes/, rather than saying they are not /meta/.

What I was trying to focus on is the tendency for folks to call /any/
singleton class a metaclass. I was just arguing that not all singleton
classes are metaclasses. I guess we can continue to discuss whether some
subset of singleton classes might be metaclasses.
Aww, don't you like the _ in my RCR? :) (singleton_class)

I should have refered to the RCR before responding. I added my vote in
favor of it!
 
D

David A. Black

Hi --

David A. Black said:

I think you misunderstand "properties". It is true that the class does
not (directly) influence the attributes/instance variables of an object.
But properties also include the methods of the object, which are directly
influenced by the class.

I was actually thinking of methods, mainly. And you've swapped in a
new wording :) I'd go along with "directly influenced", but not
"determined"; that is, an object's "birth class" certainly has a role
to play in the object's method capabilities, but is not a determinant.
Actually, the objections regarding "making objects" and "instance variable
properties" goes more to saying that the singleton classes of classes are
not /classes/, rather than saying they are not /meta/.

I must have garbled something I said somewhere along the line; I
definitely would never (knowingly :) suggest that singleton classes
are not classes. See below....
What I was trying to focus on is the tendency for folks to call /any/
singleton class a metaclass. I was just arguing that not all singleton
classes are metaclasses. I guess we can continue to discuss whether some
subset of singleton classes might be metaclasses.

What I got from the quotation, and your gloss on it, was that
"metaclass" is recognized (outside of Ruby) to mean a factory for
classes, and that therefore it could be used to refer to a Class
object's singleton class. I would argue the opposite: singleton
classes, in every case, are non-factories, so to the extent that
"metaclass" might suggest factory-ness (i.e., factory of Class
objects), it could be misleading -- not only as a general term for
"singleton class" (which we both agree it isn't), but even as a
specialized term for "singleton class of Class object".

Correspondingly, if there is a "template for making cookie cutters
themselves" (to paraphrase) in Ruby, it would be the object Class
itself. So Class could be called *the* metaclass :)


David
 
J

Jim Weirich

David A. Black said:
I'd go along with "directly influenced", but not
"determined"; that is, an object's "birth class" certainly has a role
to play in the object's method capabilities, but is not a determinant.

As do all the ancestors in the
What I got from the quotation, and your gloss on it, was that
"metaclass" is recognized (outside of Ruby) to mean a factory for
classes, and that therefore it could be used to refer to a Class
object's singleton class.

The analogy in the quote did indeed focus on the creation aspect, and I
did indeed gloss over the fact that singleton classes don't create new
instances. Perhaps the analogy was poorly suited for my point.

What I was trying to communicate with the quote is that Metaclasses are to
classes what classes are to objects. As classes hold the behavior for
objects, metaclasses hold the behavior classes. A Metaclass is a class
whose instances are classes (or in the case of a singleton metaclass, whos
one and only instance is a class).
I must have garbled something I said somewhere along the line; I
definitely would never (knowingly :) suggest that singleton classes
are not classes. See below....

And just as the inability to create new instances does not disqualify
singleton classes from being classes, the inability for a singleton
metaclass does not disqualify it from being a metaclass.
Correspondingly, if there is a "template for making cookie cutters
themselves" (to paraphrase) in Ruby, it would be the object Class
itself.

Indeed, Class is the Metaclass from which all the singleton metaclasses
derive.
 
J

Jim Weirich

Jim Weirich said:
As do all the ancestors in the
Oops ............................^^^^^^^^

Sorry, a half formed thought escaped through my fingers. Just ignore this
part.
 
D

David A. Black

Hi --

David A. Black said:

As do all the ancestors in the


The analogy in the quote did indeed focus on the creation aspect, and I
did indeed gloss over the fact that singleton classes don't create new
instances. Perhaps the analogy was poorly suited for my point.

What I was trying to communicate with the quote is that Metaclasses are to
classes what classes are to objects. As classes hold the behavior for
objects, metaclasses hold the behavior classes. A Metaclass is a class
whose instances are classes (or in the case of a singleton metaclass, whos
one and only instance is a class).

Although... here's something interesting:

irb(main):001:0> a = ""
=> ""
irb(main):002:0> c = (class << a; self; end)
=> #<Class:#<String:0x401f8b6c>>
irb(main):003:0> a.instance_of?(c)
=> false
irb(main):004:0> a.instance_of?(String)
=> true
irb(main):005:0> s = class << String; self; end
=> #<Class:String>
irb(main):006:0> String.instance_of?(s)
=> false
irb(main):007:0> String.instance_of?(Class)
=> true

I guess being an instance_of something is a unique relationship (only
one class-of-which-you-are-an-instance to a customer), and having a
singleton class doesn't mean you're an instance of it. That seems to
reinforce the non-factory aspect of all singleton classes, in the
sense that it disallows even the one "instance of" relationship that
one might have expected them to claim to have. (I expected it -- I
think I once knew, but had forgotten about, the above behavior.)
And just as the inability to create new instances does not disqualify
singleton classes from being classes, the inability for a singleton
metaclass does not disqualify it from being a metaclass.

OK... but that, again, is where the quotation then becomes confusing,
since its chief point is that a "metaclass" is, specifically, a
factory for classes. If we use the word "metaclass" to mean singleton
class of a class, we're definitely giving up any "cookie-cutter"
analogy, and that seemed to be the whole thrust of that quotation.
Indeed, Class is the Metaclass from which all the singleton metaclasses
derive.

And all other Class objects too. But then "[Mm]etaclass" becomes
really kind of overloaded -- in the sense that on the one hand it is a
suitable term for Class (which is truly the thing that stamps out the
cookie cutters themselves), while on the other hand it gets used as a
term for something which is unequivocally *not* in the cookie-cutter,
meta-cookie-cutter, or factory family at all.


David
 
J

Jim Weirich

Although... here's something interesting:
[... elided IRB session that illustrates that singleton classes have no
instances ...]

Wow ... I didn't see that coming. That has implications for elsewhere in the
thread discussing the Ruby object model diagram where everyone is drawing
ASCII art with arrows labeled "instance-of". All those diagrams are rendered
invalid in one fell swoop. Wow. (I notice that Matz's diagram in the RI docs
does not explicitly label the horizontal arrows "instance-of" ).

So, what do we call the relationship between a class and its singleton class?
"singleton-instance-of"? Maybe.

Given that the Forman/Danforth formal definition of a metaclass is "A
metaclass is an object whose instances are classes", then the only
Forman/Danforth metaclass in Ruby is the class Class.

Although, after rereading the first few chapters of the book, it is clear that
the Class singleton classes fulfill a very similar role to the classical
Forman/Danforth metaclasses. One could argue that Forman's use of
"instance-of" really maps to "singleton-instance-of" ... but at that point we
are arguing definitions and it not worth pursuing.
I guess being an instance_of something is a unique relationship (only
one class-of-which-you-are-an-instance to a customer), and having a
singleton class doesn't mean you're an instance of it. That seems to
reinforce the non-factory aspect of all singleton classes, in the
sense that it disallows even the one "instance of" relationship that
one might have expected them to claim to have. (I expected it -- I
think I once knew, but had forgotten about, the above behavior.)

It also makes the name "Singleton" class a little odd. I thought it was
because a singleton class could only have a single instance. Now I find out
it can't even have that. Perhaps they should be Zeroton classes :)
And all other Class objects too.

Only things (that would be called metaclasses if they could only have
instances) are derived (i.e. inherit) from Class. All other class objects
are merely instances of Class.
But then "[Mm]etaclass" becomes
really kind of overloaded -- in the sense that on the one hand it is a
suitable term for Class (which is truly the thing that stamps out the
cookie cutters themselves), while on the other hand it gets used as a
term for something which is unequivocally *not* in the cookie-cutter,
meta-cookie-cutter, or factory family at all.

The formal definition does not require metaclasses (or classes) to create
instances ... only that they /have/ instances (which is you so clearly
demonstrated singleton classes have no instances). The factory aspect was
entirely part of the analogy and not part of the formal definition.
 
P

Pit Capitain

David said:
Although... here's something interesting:

irb(main):001:0> a = ""
=> ""
irb(main):002:0> c = (class << a; self; end)
=> #<Class:#<String:0x401f8b6c>>
irb(main):003:0> a.instance_of?(c)
=> false
irb(main):004:0> a.instance_of?(String)
=> true
irb(main):005:0> s = class << String; self; end
=> #<Class:String>
irb(main):006:0> String.instance_of?(s)
=> false
irb(main):007:0> String.instance_of?(Class)
=> true

But note that

irb(main):001:0> a = ""
=> ""
irb(main):002:0> c = (class << a; self; end)
=> #<Class:#<String:0x2dae6d0>>
irb(main):003:0> c === a
=> true

Regards,
Pit
 
D

David A. Black

Hi --

It also makes the name "Singleton" class a little odd. I thought it was
because a singleton class could only have a single instance. Now I find out
it can't even have that. Perhaps they should be Zeroton classes :)

I always thought it was singleton in the sense that, unlike the "birth
class", it was not shared with other objects. There is of course a
long history of discussion about the term "singleton", and the fact
that it's overloaded.... I've suggested "own class", and others have
suggested other terms, though I don't know that even a pronouncement
from Matz will change usage completely.
Only things (that would be called metaclasses if they could only have
instances) are derived (i.e. inherit) from Class. All other class objects
are merely instances of Class.

But being a (mere) instance of Class is, I think, by far the closest
thing in Ruby to matching the proto-cookie-cutter thing. (I know
that's just an analogy, but Class actually fits it rather well.) Not
that every instance of Class is a metaclass, but rather that Class is
a metaclass, on account of the fact that it can create new classes
(meta or otherwise).
But then "[Mm]etaclass" becomes
really kind of overloaded -- in the sense that on the one hand it is a
suitable term for Class (which is truly the thing that stamps out the
cookie cutters themselves), while on the other hand it gets used as a
term for something which is unequivocally *not* in the cookie-cutter,
meta-cookie-cutter, or factory family at all.

The formal definition does not require metaclasses (or classes) to create
instances ... only that they /have/ instances (which is you so clearly
demonstrated singleton classes have no instances). The factory aspect was
entirely part of the analogy and not part of the formal definition.

Like "singleton", though, this may be a case where Matz isn't using it
in a way that fits precisely with any previous formal definitions. I
guess that's one of the hazards of writing a language with a cool,
uncommon design :)


David
 
D

David A. Black

Hi --

But note that

irb(main):001:0> a = ""
=> ""
irb(main):002:0> c = (class << a; self; end)
=> #<Class:#<String:0x2dae6d0>>
irb(main):003:0> c === a
=> true

Yes, a.kind_of(c) is true, but that's never been a one-only
relationship.


David
 
C

Carlos

Although... here's something interesting:
[... elided IRB session that illustrates that singleton classes have no
instances ...]

Wow ... I didn't see that coming. That has implications for elsewhere in the
thread discussing the Ruby object model diagram where everyone is drawing
ASCII art with arrows labeled "instance-of". All those diagrams are rendered
invalid in one fell swoop. Wow. (I notice that Matz's diagram in the RI docs
does not explicitly label the horizontal arrows "instance-of" ).

Wow, it was only me. Since when I am everyone? Thanks for the compliment,
anyway.

Before your discoveries make you jump into conclusions, you should apply a
little of scientific thought. You have two facts: one, that the diagram
shows that Object --instanceof--> (Object). The other: that

$ ruby -e 'p Object.instance_of?(class<<Object;self;end)'
false

One possible explanation for this discrepancy is that the diagram is wrong.
Another is that instance_of? doesn't take into account singleton classes.

I guess it's the second one :).

Good luck.
 
D

David A. Black

Hi --

Before your discoveries make you jump into conclusions, you should apply a
little of scientific thought. You have two facts: one, that the diagram
shows that Object --instanceof--> (Object). The other: that

$ ruby -e 'p Object.instance_of?(class<<Object;self;end)'
false

One possible explanation for this discrepancy is that the diagram is wrong.
Another is that instance_of? doesn't take into account singleton classes.

I guess it's the second one :).

instance_of? tells you (accurately, definitively) whether or not
something is an instance of something. Obviously you can draw a
diagram that posits any relationship you wish. I could write a
diagram that shows Array to be the superclass of String, for example,
and claim that #superclass "doesn't take into account" the fact that
Array is the superclass of String. But if the diagram isn't actually
diagramming Ruby's view of things, then it won't have much value.


David
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,767
Messages
2,569,572
Members
45,045
Latest member
DRCM

Latest Threads

Top