Forum: Ruby Superclass of eigenclass

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Danny O. (Guest)
on 2009-05-07 16:35
On page 261 of The Ruby P.ming Language, they state:

"Class objects are special: they have superclasses. The eigenclasses of
class objects are also special: they have superclasses, too. The
eigenclass of an ordinary object stands alone and has no superclass."

This last sentence has me puzzled. The only possible interpretations
that I can imagine would be that calling superclass on the eigenclass of
an ordinary object would result in either (a) a method not found or (b)
the value nil being returned. However, neither of these is the case.

Adding the usual eigenclass method to class Object, we then get in irb
(ruby 1.8.7 on Mac OS X):

irb> greeting = "hello"
=> "hello"
irb> greeting.eigenclass
=> #<Class:#<String:0xb7cf5a14>>
irb> greeting.eigenclass.superclass
=> #<Class:String>

I interpret #<Class:#<String:0xb7cf5a14>> as "a class object for the
string object at 0xb7cf5a14".
I interpret #<Class:String> as "a class object for class String".

This seems reasonable but conflicts with the description given in TRPL
at the top. Any ideas?

Danny.

P.S. In my searches before posting I came across the following that
no-one replied to. It seems that there are variations on the behaviour.

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/...
Gregory B. (Guest)
on 2009-05-07 17:25
(Received via mailing list)
On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv 
<removed_email_address@domain.invalid>
wrote:
> On page 261 of The Ruby P.ming Language, they state:
>
> "Class objects are special: they have superclasses. The eigenclasses of
> class objects are also special: they have superclasses, too. The
> eigenclass of an ordinary object stands alone and has no superclass."
>
> This last sentence has me puzzled. The only possible interpretations
> that I can imagine would be that calling superclass on the eigenclass of
> an ordinary object would result in either (a) a method not found or (b)
> the value nil being returned. However, neither of these is the case.

Not exactly an answer to your question, but here are some thoughts.

>> class A
>>   p ancestors
>> end
[A, Object, Kernel]

>> class A
>>   f = class << self; self; end
>>   p f.ancestors
>> end
[Class, Module, Object, Kernel]

>> a = "a"
=> "a"
>> k = class << a; self; end
=> #<Class:#<String:0x25ad14>>
>> k.ancestors
=> [String, Enumerable, Comparable, Object, Kernel]
Rick D. (Guest)
on 2009-05-07 19:51
(Received via mailing list)
On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv 
<removed_email_address@domain.invalid>
wrote:
> On page 261 of The Ruby P.ming Language, they state:
>
> "Class objects are special: they have superclasses. The eigenclasses of
> class objects are also special: they have superclasses, too. The
> eigenclass of an ordinary object stands alone and has no superclass."

I'm pretty sure that this is a typo.

Eigenclasses of ordinary objects certainly do have superclasses,
that's how methods not defined in the singleton class sent to the
ordinary object get resolved.

Two things that the eigenclass of an ordinary object can't have that
and eigenclass of a class (which I for one prefer to call a metaclass)
can have is:

1. A subclass
2. Any instances besides that singleton ordinary object, which is why
you get an exception of you try to send new to such an eigenclass.

I've long maintained that Ruby would be quite a bit clearer if we
cleaned up this singleton vs. eigen vs. meta class thing.  The fact
that MRI uses a single flag bit marked singleton for both singleton
classes and metaclasses, an implementation artifact which is pretty
much hidden by the internal implementation of methods like class,
ancestors etc. just tends to confuse people.

But that's just my opinion.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
Rick D. (Guest)
on 2009-05-07 20:22
(Received via mailing list)
On Thu, May 7, 2009 at 11:50 AM, Rick DeNatale 
<removed_email_address@domain.invalid>
wrote:
> On Thu, May 7, 2009 at 8:35 AM, Danny O cuiv <removed_email_address@domain.invalid> 
wrote:
>> On page 261 of The Ruby P.ming Language, they state:
>>
>> "Class objects are special: they have superclasses. The eigenclasses of
>> class objects are also special: they have superclasses, too. The
>> eigenclass of an ordinary object stands alone and has no superclass."
>
> I'm pretty sure that this is a typo.

Just for the record, I just submitted the following erratum report to
the O'Reilly site for the book:

Page 261 2nd Paragraph:
The paragraph says:

"Class objects are special: they have superclasses. The eigenclasses of
class objects are also special: they have superclasses, too. The
eigenclass of an ordinary object stands alone and has no superclass."

Both the eigenclass of a class object and the eigenclass of an
ordinary object have a superclass.  If not then sending a message to
an ordinary object would end up invoking method_missing.

I think that the paragraph should read:

"Class objects are special: they can have subclasses. The eigenclasses
of
class objects are also special: they can have subclasses, too. The
eigenclass of an ordinary object can have neither a subclass, nor any
other instance except that single ordinary object.  If an ordinary
object with an eigenclass is duplicated with the Object#dup method,
the duplicate will not acquire any of it's singleton methods. If it is
cloned with the Object#clone method, the result will get an eigenclass
which is a duplicate of the original objects eigenclass, so that each
eigenclass has but a single instance."

The following ruby code (which behaves identically on Ruby 1.8.6,
1.8.7 and 1.9.1) illustrates the above:

module Kernel
  def eigenclass
    class << self;self;end
  end
end

class TestClass

  def bar
    :bar
  end

  def self.foo
    :foo
  end
end

t = TestClass.new
def t.gorp
  :gorp
end

p t_eigenclass = t.eigenclass # => #<Class:#<TestClass:0x232d0>>
p t_eigenclass.superclass # => #<Class:TestClass>

p t.bar # => :bar
p t.gorp # => :gorp

p t_dup = t.dup
p t_clone = t.clone
p t_clone.respond_to?(:gorp) # => true
p t_clone.eigenclass == t_eigenclass # => false
p t_dup.respond_to?(:gorp) # => false

p t.class.foo # => :foo
p t.eigenclass.foo # => :foo


--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
Danny O. (Guest)
on 2009-05-07 21:17
Hi Rick,

I suspect that you're right that the text is incorrect. I doubt that
it's a typo (in the sense of something that was fat-fingered) as the
three sentences, taken together, are consistent in what they express. As
such, it seems mistaken, which makes me curious to know what they were
intending to say.

Your investigation of the issue corresponds with mine. I would, however,
take issue with an aspect of your revised wording, specifically the
following:

> The eigenclass of an ordinary object can have neither a subclass,
> nor any other instance except that single ordinary object.

The ordinary object is not an instance of the eigenclass. In your
example, the ordinary object is an instance of TestClass, not of any
eigenclass. Indeed, there would be a bootstrapping problem if you
regarded the ordinary object as an instance of the eigenclass. (You can
only have an eigenclass in the context of an existing object, so you
couldn't have created that object in the first place by instantiating
the eigenclass.)

The same issue appears in the following statement:

> If it is cloned with the Object#clone method, the result will get an eigenclass
> which is a duplicate of the original objects eigenclass, so that each
> eigenclass has but a single instance."

Regards,

Danny
Rick D. (Guest)
on 2009-05-07 22:27
(Received via mailing list)
On Thu, May 7, 2009 at 1:17 PM, Danny O cuiv 
<removed_email_address@domain.invalid>
wrote:
>
> The ordinary object is not an instance of the eigenclass. In your
> example, the ordinary object is an instance of TestClass, not of any
> eigenclass.

Well instance is one of those things which the smoke and mirrors in
MRI makes muddy.

Another example is superclass.  One definition is that a is a
superclass of b if the superclass slot of b points to a.  This is the
sense that the superclass of a class'es eigenclass is the eigenclass
of the classes superclass.

But if you define superclass as what gets returned by the superclass
method, then MRI obscures the truth:

String.eigenclass # => #<Class:String>
Object.eigenclass # => #<Class:Object>
String.superclass # => Object
String.eigenclass.superclass # => #<Class:Class>

If you go in and look at the implementation, you'll find that the
eigenclass of String has a superclass slot which points to the
eigenclass of Object, but the superclass method implementation skips
past 'singleton' classes, until it gets to <Class:Class>

Now the instance_of? method does the same thing, it skips over
'singleton' classes.

So what I'm really talking about is that a singleton class of an
ordinary object has a singleton instance, which is the only meaning of
singleton class which ever made sense to me.

> Indeed, there would be a bootstrapping problem if you
> regarded the ordinary object as an instance of the eigenclass. (You can
> only have an eigenclass in the context of an existing object, so you
> couldn't have created that object in the first place by instantiating
> the eigenclass.)

That's only if you tie the notion of instantiation and instance too
closely, I don't see it that way.

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
Robert D. (Guest)
on 2009-05-07 22:28
(Received via mailing list)
On Thu, May 7, 2009 at 7:17 PM, Danny O cuiv 
<removed_email_address@domain.invalid>
wrote:
> following:
> the eigenclass.)
I did not read that Rick said anything about instantiating, but for
what I am concerned he sure is right
because of this:

irb(main):006:0> a=Object::new
=> #<Object:0x872e658>
irb(main):007:0> s=class << a; self end
=> #<Class:#<Object:0x872e658>>
irb(main):008:0> a.is_a? s
=> true
irb(main):009:0> s::new
TypeError: can't create instance of singleton class
  from (irb):9:in `new'
  from (irb):9
  from /usr/local/bin/irb:12:in `<main>'

Cheers
R.
Danny O. (Guest)
on 2009-05-08 00:38
Rick, Robert,

Thanks for your helpful replies. I have just introduced myself to Ruby
in the last couple of weeks by reading The Ruby P.ming Language, so
I'm still trying to pin some concepts. One thing I have found
interesting in looking things up online is that it's not uncommon to
refer to C-level constructs in MRI when discussing language semantics.
(I personally would prefer to restrict myself to what's observable from
sample Ruby code.)

Firstly, Robert, you have used "is_a?" in your example. This tests for
(direct or indirect) conformance. I quibbled with the notion that the
ordinary object was an instance of the eigenclass. The normal usage of
the term "instance" to mean "direct instance" is reflected in the
semantics of Ruby's "instance_of?" method. Using this method, we could
extend your sample code as follows:

irb> a.instance_of? s
=> false
irb> a.instance_of? Object
=> true

This is what I meant, and to me, this is significant. One of my
reference points in reading about Ruby was Smalltalk, which has the
notion of a metaclass. In Smalltalk the concept is clear. (Indeed, the
only reasonable meaning for the term metaclass is "a class whose
instances are classes".) In Ruby, some people contend that eigenclass
and metaclass are synonyms, which seems to me to confuse two distinct
notions. In the interests of conceptual clarity, here's my take on the
two notions. (Feel free to poke holes in this if it's totally
upside-down or otherwise mistaken.)

(a) Eigenclass
Ruby allows for per-instance methods (deliberately avoiding the more
common term as it's overloaded with a well-known pattern). The
conceptual container for these per-instance methods is the object's
eigenclass. The precise implementation of this notion in the reference
notion should be immaterial. What is important is that a decision was
made to reify the notion by providing language syntax to open it up, as
follows:
class << myObject
This allows for dealing with several per-instance methods together. More
to the point, if this syntax was not part of the language, eigenclasses
would be purely an implementation notion and have no correspondence in
Ruby code.

(b) Metaclass
To me, there is only one metaclass in Ruby, namely class Class. (By any
reasonable definition of the term metaclass.) It seems to me mistaken to
equate the terms metaclass and eigenclass. For one thing, every object
in Ruby has an eigenclass (not just class objects). Secondly, even if we
restrict our consideration purely to eigenclasses of class objects,
these don't really qualify as metaclasses either. In Smalltalk, every
class object is a (direct) instance of a metaclass. In Ruby, class
objects are not (direct) instances of any eigenclass; they are all
(direct) instances of class Class.

From this, it would seem to me that the term metaclass should not be
used in Ruby. (Flanagan and Matz possibly agree as they seem to largely
avoid the term in their book).

I would, however, agree with Rick about the muddiness surrounding
superclasses. For example, the example on page 294-295-296 of the book
uses the eigenclass to wrap tracing code around methods. In doing so,
they use a call to super to access the original implementation. Now
super, by the definition on page 238, "invokes a method with the same
name as the current one, in the superclass of the current class". So,
for this to work, the superclass of the eigenclass needs to be the
original class. In other words, let's say we have a class called X, an
instance of that class called x and let's say the eigenclass of x is e.
The method on page 294 will work if the superclass of e is X. (Because
that's where the original implementation is defined.) However, this is
not the case. The superclass of the eigenclass is not the original
class. It is the eigenclass of the original class. Finally, note that in
saying "the superclass of the eigenclass is not the original class", it
would appear that it was at one stage. According to Paolo Nusco
Perrotta, at least some implementations of 1.8.2 and 1.9 had this
behaviour:

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/...

(link repeated from my original post).

Regards,

Danny.
Robert D. (Guest)
on 2009-05-08 10:46
(Received via mailing list)
On Thu, May 7, 2009 at 10:39 PM, Danny O cuiv 
<removed_email_address@domain.invalid>
wrote:
> Rick, Robert,
It seems that language is very important :) my English and my
Smalltalk are very far of those of Rick, and I have realized that
indeed he read very much better what you meant.

However, although I agree that those terms are somehow not defined up
to the last detail in Ruby, and I have occasionaly explained about it,
I just wanted to give you a practical example.
It is very good to have some unbiased views on things.

But in reality singleton classes, yes that is what I prefer ;) are
very simple because you really never care too much about their
inheritance. The more I work with Ruby the less I care about
inheritance in general.

Cheers
Robert
--
Si tu veux construire un bateau ...
Ne rassemble pas des hommes pour aller chercher du bois, préparer des
outils, répartir les tâches, alléger le travail… mais enseigne aux
gens la nostalgie de l’infini de la mer.

If you want to build a ship, don’t herd people together to collect
wood and don’t assign them tasks and work, but rather teach them to
long for the endless immensity of the sea.
Robert D. (Guest)
on 2009-05-08 10:47
(Received via mailing list)
On Fri, May 8, 2009 at 8:45 AM, Robert D. <removed_email_address@domain.invalid>
wrote:
> On Thu, May 7, 2009 at 10:39 PM, Danny O cuiv <removed_email_address@domain.invalid> 
wrote:
>
> However, although I agree that those terms are somehow not defined up
> to the last detail in Ruby, and I have occasionaly explained about it,
Sorry: occasionally complained
Danny O. (Guest)
on 2009-05-11 16:41
Rick, Robert,

Thanks again for your replies.

Rick wrote:

> If you go in and look at the implementation, you'll find that the
> eigenclass of String has a superclass slot which points to the
> eigenclass of Object, but the superclass method implementation skips
> past 'singleton' classes, until it gets to <Class:Class>

To me, that smacks of being ad hoc and inconsistent. The superclass
method implementation skips past 'singleton' classes, until it gets to
#<Class:Class>. But #<Class:Class> is itself a 'singleton' class, so I
can't see the rationale there. In other words, I can't really grasp what
semantics are being exposed.

Robert wrote:

> But in reality singleton classes, yes that is what I prefer ;) are
> very simple because you really never care too much about their
> inheritance. The more I work with Ruby the less I care about
> inheritance in general.

I would disagree that one would never really care too much about an
eigenclass's inheritance. Example 8-10 on page 294 of the Flanagan/Matz
book details a very nice-looking technique for doing interception. (The
particular example uses the technique to wrap tracing code.) This
technique depends on accessing the original implementation of the method
by calling super in an eigenclass, so the inheritance of the eigenclass
is crucial here.

In attempting to understand why this might work, I have four conflicting
viewpoints. Say I have a class X that I instantiate to get a regular
object x. Say that the eigenclass of x is e. For the interception
technique to work, X needs to be above e in the inheritance hierarchy.

(i) The Flanagan/Matz book says that an eigenclass of a regular object
doesn't have a superclass. (So that e has no superclass.) Clearly this
is incorrect.

(ii) Exploring using the superclass method gives:
e.superclass    # => #<Class:X>
e.superclass.superclass    # => #<Class:Class>
e.superclass.superclass.superclass    # => #<Class:Class>
with the same result for any further calls to superclass. This indicates
that X is not in the inheritance hierarchy of e and consequently the
technique should not work.

(iii) Exploring using the ancestors method gives:
e.ancestors    # => [X, Object, Kernel]
This indicates that X is in the inheritance hierarchy of e and
consequently the technique should work.

(iv) Exploring using is_a?
x.is_a? e    # => true
This indicates that e is in the inheritance hierarchy of X (i.e. the
opposite of the previous indication) and consequently the technique
should not work.

I'd have to confess that this seems like a conceptual mess to me. I
presume that I'm grasping the wrong end of some stick or other. Can
anyone help point out what that might be?

Regards,

Danny
Robert D. (Guest)
on 2009-05-12 14:17
(Received via mailing list)
On Mon, May 11, 2009 at 2:42 PM, Danny O cuiv 
<removed_email_address@domain.invalid>
wrote:
>
>> inheritance. The more I work with Ruby the less I care about
>> inheritance in general.
>
> I would disagree that one would never really care too much about an
> eigenclass's inheritance. Example 8-10 on page 294 of the Flanagan/Matz
> book details a very nice-looking technique for doing interception. (The
> particular example uses the technique to wrap tracing code.) This
> technique depends on accessing the original implementation of the method
> by calling super in an eigenclass, so the inheritance of the eigenclass
> is crucial here.
yes but I was talking about the other direction in the inheritance
tree, the super class of a singleton class is very well defined as the
class of the singleton's class object's class. Are we cycling here ;)?

Cheers
Robert
--
Si tu veux construire un bateau ...
Ne rassemble pas des hommes pour aller chercher du bois, préparer des
outils, répartir les tâches, alléger le travail… mais enseigne aux
gens la nostalgie de l’infini de la mer.

If you want to build a ship, don’t herd people together to collect
wood and don’t assign them tasks and work, but rather teach them to
long for the endless immensity of the sea.
Danny O. (Guest)
on 2009-05-12 18:38
Robert D. wrote:
> the super class of a singleton class is very well defined as the
> class of the singleton's class object's class.

Robert,

I mustn't be making myself clear.
I fully agree with your statement above. Because the language can get a
bit dense, it's probably clearer to adopt a notation (as I did before)
of a class called X, an instance of X called x and the eigenclass of x
called e.

The superclass of e is (as you say) the eigenclass of X (i.e.
#<Class:X>). The superclass of this is the eigenclass of class Class
(i.e. #<Class:Class>). No problem with this whatsoever. I wouldn't go so
far as to say it's well-defined, because it was different in 1.8.2 and
in some versions of 1.9, but that's a separate issue which we can leave
to one side.

However, what is clear from the above is that X is not a superclass of
e. This is a problem for two reasons:

(i) Certain metaprogramming techniques (e.g the one on page 295 or RPL)
involve calling super in an eigenclass method, with the intention of
picking up the implementation of the same method in the original class.
If X is not a superclass of e, this shouldn't work. But it does.

(ii) Calling the ancestors on e gives:
e.ancestors    # => [X, Object, Kernel]
So we have X appearing as an ancestor of e, when it is neither a
superclass of e nor an included class in e.

Somebody here must have a better handle on this than me. Please chip in
if you do.

Thanks,

Danny.
Gary W. (Guest)
on 2009-05-12 20:02
(Received via mailing list)
On May 12, 2009, at 10:38 AM, Danny O cuiv wrote:
> (ii) Calling the ancestors on e gives:
> e.ancestors    # => [X, Object, Kernel]
> So we have X appearing as an ancestor of e, when it is neither a
> superclass of e nor an included class in e.
>
> Somebody here must have a better handle on this than me. Please chip
> in
> if you do.

I think you need to decouple the inheritance relationships (what
superclass reveals) from the method lookup chain (what ancestor
partially reveals) in order to understand the semantics. Arguably this
could all be clearer via some better naming.

Confusion comes from:
-- the super keyword uses the method lookup chain, not the superclass
chain
-- the ancestor method reports on the method lookup chain, not the
inheritance chain
-- the ancestor method doesn't show eigenclasses, they are implied
Danny O. (Guest)
on 2009-05-12 20:29
Gary W. wrote:
> Confusion comes from:
> -- the super keyword uses the method lookup chain, not the superclass
> chain
> -- the ancestor method reports on the method lookup chain, not the
> inheritance chain

Aaaah! The penny finally drops! Thanks a million for this, Gary. I think
I'd have been banging my head against a brick wall for ages without your
explanation.

I'd probably still stand by my earlier assertion that it's a conceptual
mess, however. It's just that now that I know what the semantics really
are, I can work with it. Bad naming trips up even very experienced
people. For example, in RPL, no lesser luminaries than David Flanagan
and Matz write on page 238 that super "invokes a method with the same
name as the current one, in the superclass of the current class". Given
your first point above, it's clear that this is not just misleading,
it's also Just Plain Wrong (tm).

That said, for my own purposes, I now have a pretty good picture of the
semantics (naming snafus and all) and can definitely work with that
picture. So thanks again.

Regards,

Danny
David Flanagan (Guest)
on 2009-05-14 01:56
(Received via mailing list)
On May 7, 5:35 am, Danny O cuiv <removed_email_address@domain.invalid> wrote:
> On page 261 of The Ruby P.ming Language, they state:
>
> "Class objects are special: they have superclasses. The eigenclasses of
> class objects are also special: they have superclasses, too. Theeigenclassof an ordinary 
object stands alone and has nosuperclass."

The text you quote does not match the behavior of any version of Ruby
I can find--I don't recall what I was thinking when I wrote this.
I'll fix this. The description of how method lookup works (and how
class methods are inherited) is conceptually correct, however.

I think it is best to regard the superclass of an eigenclass as an
implementation-defined construct, and not something you can rely on.
As noted throughout this thread, Ruby has fuzzy boundaries between
implementation and specification.  And also, superclass and related
methods play some tricks on you.  The link you provide to an earlier
ruby-talk message points out that the superclass of an eigenclass is
one way in 1.8.2 and 1.9.x, and is another way in 1.8.6 and 1.8.7.
My experimentation shows that jruby 1.0 works the way ruby 1.9 does in
this regard.

Let's discuss only Ruby 1.9 for now.  In this version, I believe that
if o is an object that is not a class, then:

    o.eigenclass.superclass == o.class

Given this, then the method lookup algorithm for o is simple to
describe.  Begin with the eigenclass of o and climb the superclass
chain until the method is found.  (Where the superclass chain is not
the same thing that is returned by the superclass method, because the
superclass method skips over modules)

Now suppose that o is the Fixnum class, and let's use ' to designate
an eigenclass: Fixnum', Integer' and so on.  In this case, methods are
looked up in this hierarchy:

   Fixnum'->Integer'->Numeric'->Object'->BasicObject'->Class->Module-
>Object->Kernel->BasicObject

Notice that the eigenclass of the Comparable module is omitted here.
Fixnum does not inherit class methods from ancestors that are modules.

I believe that method inheritance works the same way in all recent
versions of ruby, but that the observability of the inheritance chain
through eigenclasses varies.  Don't try this with Ruby 1.8.6 or Ruby
1.8.7.
David Flanagan (Guest)
on 2009-05-14 02:05
(Received via mailing list)
On May 7, 9:21 am, Rick DeNatale <removed_email_address@domain.invalid> wrote:
> Just for the record, I just submitted the following erratum report to
> the O'Reilly site for the book:

Rick,

It wasn't a typo, and it correctly describes how method inheritance
works, but it doesn't reflect the reality of the superclass method of
eigenclasses.

Your suggested replacement text won't work as a replacement--the point
of the paragraph in question is to explain method inheritance, not to
get into the nitty gritty about eigenclasses.

Having said that, I should perhaps try to fit some of these eigenclass
details into my next edition, as well as your argument for why the
term "singleton class" makes sense.

    David Flanagan
David Flanagan (Guest)
on 2009-05-14 02:11
(Received via mailing list)
On May 11, 5:42 am, Danny O cuiv <removed_email_address@domain.invalid> wrote:
> To me, that smacks of being ad hoc and inconsistent. Thesuperclass
> method implementation skips past 'singleton' classes, until it gets to
> #<Class:Class>. But #<Class:Class> is itself a 'singleton' class, so I
> can't see the rationale there. In other words, I can't really grasp what
> semantics are being exposed.

The implementation details are leaking.  No semantics should be read
into this, I think.

> I'd have to confess that this seems like a conceptual mess to me. I
> presume that I'm grasping the wrong end of some stick or other. Can
> anyone help point out what that might be?

It is a conceptual mess.  It seems somewhat clearer, however, with
Ruby 1.9.
David Flanagan (Guest)
on 2009-05-14 02:20
(Received via mailing list)
On May 12, 9:29 am, Danny O cuiv <removed_email_address@domain.invalid> wrote:
> Gary W. wrote:
> > Confusion comes from:
> > -- the super keyword uses the method lookup chain, not thesuperclass
> > chain
> > -- the ancestor method reports on the method lookup chain, not the
> > inheritance chain

I have to disagree with Gary's nomenclature.  Inheritance and method
lookup are basically the same thing, so trying to distinguish "method
lookup chain" from "inheritance chain" is hard to do.  Maybe we can
say "class hierarchy" when we want to exclude modules as the
superclass method does and "method inheritance chain" (or something)
when we want to include modules.

> Aaaah! The penny finally drops! Thanks a million for this, Gary. I think
> I'd have been banging my head against a brick wall for ages without your
> explanation.
>
> I'd probably still stand by my earlier assertion that it's a conceptual
> mess, however. It's just that now that I know what the semantics really
> are, I can work with it. Bad naming trips up even very experienced
> people. For example, in RPL, no lesser luminaries than David Flanagan
> and Matz write on page 238 that super "invokes a method with the same
> name as the current one, in thesuperclassof the current class".

You're right.  I should have said something like "in the nearest
ancestor of the current class" or something to that effect, so that
modules are included.  I may also want to update this paragraph to
point out that a singleton method of an object can chain to a regular
instance method of the object.

Thanks for pointing out this error!
Gary W. (Guest)
on 2009-05-14 08:29
(Received via mailing list)
On May 13, 2009, at 6:20 PM, David Flanagan wrote:

> On May 12, 9:29 am, Danny O cuiv <removed_email_address@domain.invalid> wrote:
>> Gary W. wrote:
>>> Confusion comes from:
>>> -- the super keyword uses the method lookup chain, not thesuperclass
>>> chain
>>> -- the ancestor method reports on the method lookup chain, not the
>>> inheritance chain
>
> I have to disagree with Gary's nomenclature.

No problem. I just made them up for that post.

> Inheritance and method
> lookup are basically the same thing, so trying to distinguish "method
> lookup chain" from "inheritance chain" is hard to do.

But since they are only 'basically the same' and not exactly the same
it is important to distinguish between them. This is more important in
1.8.X than in 1.9.X since in 1.9.X 'superclass' tracks the method
lookup chain more closely.  In 1.8.X 'superclass' is pretty hard to
explain when you try to include singleton classes.

> Maybe we can say "class hierarchy" when we want to exclude modules
> as the
> superclass method does and "method inheritance chain" (or something)
> when we want to include modules.

I could quibble with those definitions, but my main point was that
'ancestors' doesn't match the 'superclass chain' (because of modules)
nor does it always match the 'method lookup chain' (because of
eigenclasses).

Gary W.
Joshua B. (Guest)
on 2009-05-14 08:58
(Received via mailing list)
On May 13, 2009, at 6:10 PM, David Flanagan wrote:

>>
> into this, I think.
>
>> I'd have to confess that this seems like a conceptual mess to me. I
>> presume that I'm grasping the wrong end of some stick or other. Can
>> anyone help point out what that might be?
>
> It is a conceptual mess.  It seems somewhat clearer, however, with
> Ruby 1.9.

I agree completely. In fact, beyond implementation detail, is there
any reason that eigenclasses exist in their semi-privileged realm? For
example, I've never completely understood why the following shouldn't
work:

 >> class Test
 >>   def eigenclass
 >>     class<<self
 >>       self
 >>     end
 >>   end
 >> end
=> nil
 >> TestSubEigen = Class.new(Test.new.eigenclass)
TypeError: can't make subclass of virtual class
  from (irb):43:in `initialize'
  from (irb):43:in `new'
  from (irb):43

In fact, it seems like the existence of eigenclasses is, to begin
with, an implementation detail. As it turns out, they can be very
handy for implementing instance-specific methods, but then isn't that
the point of a Prototype inheritance model?

Personally, I would like to see Ruby 2.0 formalize Ruby's prototyping
abilities. The semantics of "Test.new" could remain the same and be
conceptually identical to "Test.prototype.prototype". That is,
eigenclasses would be prototype objects that sit between the object
and its parent class object. This would have the added benefit of
clearing up the method call chain concept, as it would simply follow
the trail of prototypes.

Just ideas...

Cheers,

Josh
Jörg W Mittag (Guest)
on 2009-05-15 04:20
(Received via mailing list)
Robert D. wrote:
> However, although I agree that those terms are somehow not defined up
> to the last detail in Ruby, and I have occasionaly explained about it,

You mean "complained", right? Yes, it is kind of unfortunate, that we
ended up with this confusion. I would like to point out, however, that
this is basically a historical accident, and not anybody's (certainly
not matz's) fault.

The fundamental problem is that matz has always refused (and still
refuses) to pick a name. And over time he has done that for two
different reasons. Originally, he considered singleton classes to be a
private implementation detail of MRI, and he envisioned that there
would be other implementations that would choose to implement
singleton methods differently. He wanted to have per-object methods,
and he needed something to store them in, so he chose something that
was *already* supported by MRI: a class. Additionally, this meant that
he needed exactly 0 changes to the method resolution algorithm, and
only one single if-condition in the superclass algorithm. *And* he
could reuse that same solution for mixins.

Unfortunately, that supposedly private implementation was leaked to
the programmer, exactly *because* the singleton class is "just a
class". Due to the way class bodies work (namely that they return the
value of the last expression inside the body instead of the class
object, and that self is bound to the class object), you can get
access to the singleton class with the 'class << self; self end' trick
(or its equivalent).

As soon as you can get access to something, you need to name it. And
people did. They named it singleton class, eigenclass, virtual class,
hidden class, metaclass and dozens more ...

Which brings us to the present. *Now* matz refuses to pick a name,
because he doesn't want to ... well, *pick* a name. He wants the
*community* to pick a name, and he will simply approve whatever we
come up with. What it boils down to is that he does *not* consider
himself a "benevolent dictator", but more a "benevolent chairman" who
does not himself make decisions, but rather tries to "milk" a
consensus out of a very diverse group of very opinionated people, just
like a chairman of a senate committee would (well, at least in an
ideal world where neither the members nor the chairman are corrupt or
in any way influenced by lobbyists).

Currently, singleton class, eigenclass and metaclass are still in the
race. I agree that metaclass is wrong, but since it is the name used
by _why the lucky stiff in what is probably one of the best
introductory texts about the more esoteric corners of Ruby's object
system, a lot of Rubyists learn that name, so it is going to stick
with us. Of the other two I prefer eigenclass, both to avoid the
confusion with the singleton pattern and because it nicely fits in
with the already existing usages in mathematics (eigenvalue,
eigenvector, eigenspace, eigenmode, eigenfrequency, eigenstate,
eigenspectrum, eigenfunction, eigendecomposition, eigenproblem) and
computer science (eigenface, eigenratio).

jwm
Jörg W Mittag (Guest)
on 2009-05-15 04:25
(Received via mailing list)
Joshua B. wrote:
> In fact, it seems like the existence of eigenclasses is, to begin
> with, an implementation detail.

Originally, they were.

> As it turns out, they can be very
> handy for implementing instance-specific methods,

Exactly. It is my understanding that they were only added as a place
to "stick" per-object methods. MRI already had classes, so why not use
them? If you stick per-object methods in an eigenclass you need
exactly 0 new constructs in the interpreter, 0 changes to method
lookup and just one if-condition in superclass lookup. Plus, you can
also implement mixins the same way. That's a *lot* of leverage for
essentially one line of code.

AFAIK, the fact that they were exposed to the programmer is more of an
accident than a well-designed thought-out language feature.

jwm
Joshua B. (Guest)
on 2009-05-15 15:48
(Received via mailing list)
On May 14, 2009, at 8:25 PM, Jörg W Mittag wrote:

> also implement mixins the same way. That's a *lot* of leverage for
> essentially one line of code.
>
> AFAIK, the fact that they were exposed to the programmer is more of an
> accident than a well-designed thought-out language feature.

Right. So then the question: is there a compelling reason that they
should be allowed to be subclassed? (I mean, other than the obvious:
"Because that's not the way Ruby was designed" answer.) I cannot come
up with any compelling technical reason why the artificial limitation
of being unable to subclass "virtual classes"[1] should exist. I also
don't see what, besides this artificial limitation, is keeping Ruby
from having, at its heart, a fully prototype based inheritance system.

- Josh

[1] That's what the exception calls them, so I'd throw that into your
pot of valid names in the running.
Jörg W Mittag (Guest)
on 2009-05-16 02:00
(Received via mailing list)
Joshua B. wrote:
> should be allowed to be subclassed? (I mean, other than the obvious:
> "Because that's not the way Ruby was designed" answer.) I cannot come
> up with any compelling technical reason why the artificial limitation
> of being unable to subclass "virtual classes"[1] should exist. I also
> don't see what, besides this artificial limitation, is keeping Ruby
> from having, at its heart, a fully prototype based inheritance system.

There are lots of areas in Ruby, where things aren't as simple,
orthogonal or consistent as they should be. Unfortunately[1],
simplicity, orthogonality or consistency are not in any way design
goals. I really like your idea, but you need to find a more compelling
argument than "it makes eigenclasses consistent with classes and
simplifies the object system". But a full-fledged prototype system
would be pretty cool.

jwm

[1] Or fortunately? After all, Brainfuck is certainly simple,
    orthogonal and consistent ...
Gary W. (Guest)
on 2009-05-16 09:25
(Received via mailing list)
On May 15, 2009, at 7:46 AM, Joshua B. wrote:
>> Right. So then the question: is there a compelling reason that they
>> should be allowed to be subclassed? (I mean, other than the
>> obvious: "Because that's not the way Ruby was designed" answer.) I
>> cannot come up with any compelling technical reason why the
>> artificial limitation of being unable to subclass "virtual
>> classes"[1] should exist.

The purpose of an eigenclass is to hold per object methods.  As such,
there is always always a one-to-one relationship between an eigenclass
and its "eigeninstance" (sorry, but I can't think of a clearer term at
the moment).

The idea of subclassing an eigenclass contradicts that one-to-one
relationship.  If you could subclass an eigenclass, there would be no
way to cause ruby to search the new subclass for instance methods
since it wouldn't have a matching eigeninstance (sorry, again).  It
would not be in the method lookup chain of any object.

Just to be complete, I'll point out that there is a way for
eigenclasses to have a subclass and that is when the eigeninstances
are themselves classes.  This is most clear in 1.9.  If B is a
subclass of A, then B.eigenclass will be a subclass of A.eigenclass.
Even in this case A and B have to exist before their eigenclasses can
be accessed and not the other way around.

Gary W.
Robert D. (Guest)
on 2009-05-16 12:58
(Received via mailing list)
2009/5/16 Jörg W Mittag <removed_email_address@domain.invalid>:
But a full-fledged prototype system
> would be pretty cool.
But there are! There is Ara's prototype, which needs a little fix if I
am not mistaken or your humble servant's one:
http://ruby-smalltalk.blogspot.com/2007/08/no-more...
Sorry for the blog link, but I have not yet repackaged PPP into Lab419
:(.
HTH
Robert
Rick D. (Guest)
on 2009-05-17 00:36
(Received via mailing list)
On Sat, May 16, 2009 at 1:24 AM, Gary W. <removed_email_address@domain.invalid> 
wrote:
> is always always a one-to-one relationship between an eigenclass and its
>  This is most clear in 1.9.  If B is a subclass of A, then B.eigenclass will
> be a subclass of A.eigenclass.  Even in this case A and B have to exist
> before their eigenclasses can be accessed and not the other way around.

And there, IMHO, is where things break down.  If the definition of an
eigenclass is a 'class' which holds per object methods, then the class
of a class which has subclasses is not an eigenclass since it provides
methods not only to it's sole instance but also to it's instance's
subclass(es).

That's why I prefer to think of the objects which serve as the class
of a class as metaclasses, which is in line with the terminology used
in several other languages.

This whole area of Ruby reminds me a bit of Plato's cave, we see
images on the wall cast by "smoke" and "mirrors" in the
implementation, and try to name them. And the smoke has been shifting
a bit and the mirrors have been moving slightly. When you step outside
of the cave and look at the implementation you find:

There's a flag called FL_SINGLETON which when set in the header of a
class object means:


   * It will get cloned if you clone its instance
   * You can't copy it.
    * You can't make a subclass of it, unless you are ruby itself
creating a subclass in which case
     subclasses of the "singleton" metaclass are created under the
covers.
   * It will be bypassed by the Object#class method
   * It will be filtered out of the results Module#ancestors method
   * It will be skipped in the search for methods by
Module#instance_methods and it's related methods
  * Its methods are considered singleton methods
  * It has a hidden 'class' instance variable __attached__ which
points to it's sole instance
  * Its skipped over by ObjectSpace.each_object, so
ObjectSpace.each_object(Class) won't yield it.
  * It will prevent dumping by Marshall.dump

So what exactly does the singleton in FL_SINGLETON mean.  Well, it
does mean that a class marked with FL_SINGLETON has only one direct
instance. It doesn't mean in the case of a singleton class which
happens to be a metaclass that it doesn't have subclasses, just that
you as a Ruby programmer can only create or add to its subclasses by
subclassing its attached class.

And while you might think that singleton method was a synonym for
instance specific method, once again this is only true when it's a
singleton method within an instance-specific singleton class.

class Foo
    def self.blat
        :blat
    end
end

class Bar < Foo
end

Foo.singleton_methods => [:blat]
Bar.singleton_methods => [:blat]

The 2nd ed of the Pickaxe used the term "virtual class" and seems to
call the FL_SINGLETON bit the 'V' bit.  Looking at Ruby 1.8.6, the
term virtual class only appears in errors raised when you try to
   1. Try to make a subclass of a class marked with FL_SINGLETON and
you'll get the error
"can't make subclass of virtual class"
   2. Try to add a singleton method to an instance of an immediate
class (e.g. a Fixnum), since there's no klass ptr so nowhere to insert
the needed instance specific class in the lookup chain, and you'll get
the error "no virtual class for %s"
   3. Try to instantiate an instance of a class marked with
FL_SINGLETON and you'll get the error can't create instance of virtual
class"

And in Ruby 1.9, these error descriptions have all be changed to
remove the usage of "virtual class" and replace it with "singleton
class".

I kind of wish that FL_SINGLETON had actually been named FL_VIRTUAL,
or FL_HIDDEN, since what the flag does mostly is to hide such classes
in the standard library provided API. (ignoring the leak from class <
a;self;end

Back in the mists of Ruby history, it became popular to call any class
marked with FL_SINGLETON as a metaclass, probably because that's what
_why named the leak method in the Poignant Guide.

That added another layer of confusion, because to many of us metaclass
means the class of a class, and an instance-specific class ain't a
metaclass, it's a class whether it's hidden or not.

And I think that that's where the name eigenclass got coined, as an
alternative to singleton class, for better or worse.  And with the
publication of "The Ruby P.ming Language" it's gotten a bit of a
blessing from Matz, although the Ruby 1.9 implementation uses
singleton class in those errors where virtual class was used before.

I personally think that the distinction between metaclasses (in the
generally accepted sense of the class of a class) and
instance-specific classes is more important than the accidental
similarities between singleton classes used as instance-specific
classes and singleton-classes used as metaclasses.

And I guess eigenclass is not a bad term to use for a class which
provides behavior to a single instance, i.e. an instance-specific
class, but I don't like it as a term for a metaclass.

But that's just me, after all it's all just images caused by smoke and
mirrors <G>

--
Rick DeNatale

Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale
Danny O. (Guest)
on 2009-05-20 22:38
Rick Denatale wrote:
> But that's just me, after all it's all just images caused by smoke and mirrors <G>

:-) Perhaps. But there's also the more mundane possibility that it's
just inconsistent semantics and bad terminology.

There seems to be two forces contributing to this. Firstly, the
profusion of terms (many of which are clearly misnomers) is getting out
of hand, and is unhelpful to newcomers. Secondly, many people still
resort to referring to MRI runtime structures when discussing semantics
even though Ruby is now being implemented on the JVM, on the CLR, on the
Objective-C runtime and presumably elsewhere. There is now a clear need
to be able to discuss semantics at a sufficient level of abstraction,
i.e. purely in terms of what is revealed by the reflection API. If there
are any inconsistencies or anomalies revealed by the API, then this
should be addressed directly.

The central point that I think should be made here is that per-instance
behaviour has nothing to do with inheritance, per se. One obvious
language rule will be that per-instance behaviour should take precedence
over instance-common behaviour and one convenient way of implementing
that is to snap an eigenclass into the chain between the instance and
its class. But that implementation-specific runtime structure won't
serve as a definition of the semantics for implementations that work
differently. Take, for example, a "Ruby in the browser" (perhaps one
already exists?) that translates onto the JavaScript object model. It
would make perfect sense for this to implement per-instance behaviour as
object properties. The class << obj syntax would then just be a way of
manipulating the per-instance behaviour collectively. The only
assumption being that method resolution is correctly (and hopefully
efficiently) implemented. And the eigenclass would be purely a
conceptual notion, existing only as several properties of an object,
taken together. No problem whatsoever.

It seems that the snapping of eigenclasses into the structure was
intended to be a private implementation detail. Certain reflective
methods were written in such a way as to skip over the eigenclasses, as
though they were not to be regarded as part of the public (semantic)
inheritance hierarchy. However, there were one or two leaks. For
example, eigenclass.superclass reports the original class of the
instance (in 1.9 at least). And, in a similar vein, the keyword super
chains from an instance-specific method to a regular instance method.
(As it happens, it transpires that this is convenient way of enabling
interception.) Ideally, one would like to stem the leaks as far as
possible without causing too much breakage of existing code.

Here's a few conclusions I've come to. I'd be interested to hear what
others think.

(i) The correct way to present method resolution is the way
Flanagan/Matz do on page 258 of their book, i.e. as an algorithm. It's
simple, intuitive and easy to remember. Ruby implementations are free to
implement this algorithm any way that's convenient (and fast) in their
given context. The wrong way to present method resolution is the Pickaxe
approach of using diagrams from MRI's runtime structure. Apart from not
being portable (which will become a bigger and bigger problem), it's
backwards. That runtime structure exists like that in order to support
certain desired semantics. So deriving the semantics from the structure
is neither here nor there. Just state them up front.

(ii) The keyword super should just be defined to work according to the
method resolution algorithm, not the inheritance hierarchy. This is what
happens at the moment, so it's just a formalising of the de facto
situation and doesn't break anything. This would preserves the
convenient chaining from a per-instance method to the regular instance
method and makes it clear that there are potentially lots of other
useful chaining opportunities. As Gary pointed out to David earlier in
this thread, the sequence of classes produced by the method resolution
algorithm is different from the inheritance hierarchy because of module
mixin and eigenclasses. (And in Ruby, module mixin is not inheritance,
regardless of the similarity.)

(iii) The superclass method should be defined to return Object for the
eigenclass of a regular object. In other words, the original statement I
alluded to from page 261 of RPL would now be true. The current situation
(returning the class of the instance) is an implementation leak. I don't
think there would be much breakage resulting from this and it cleans
things up.

(iv) In principle, class method resolution could also be defined purely
by an algorithm, as a language rule, which would then not require
explicit semantic inheritance to work.

Lastly, the terminology situation needs to be addressed by the
community. The term eigenclass is really spot on for a conceptual
container for per-instance behaviour and it's great that RPL adopted it.
The other terms are not acceptable synonyms; they are misnomers.

(a) metaclass
Even _why, in the 2005 piece that led to the widespread use of the term
metaclass, acknowledged that the term was wrong: 'This definition
doesn’t really work with Ruby, though, since "a class which defines a
class" is simply: a Class'. The simplest way to illustrate this is to
compare Smalltalk and Ruby. In Smalltalk, if you evaluate the expression
"Integer class", you get "Integer class" (i.e. the same thing). The
answer being the same as the question is an expression of the anonymous
nature of the metaclass, but is read by a Smalltalk programmer as "the
metaclass of Integer". In Ruby, if you evaluate the expression
"Integer.class", you get "Class". Thus, even if the eigenclasses of
class objects in Ruby play a similar role to metaclasses in Smalltalk,
they are not metaclasses. By definition.

(b) singleton class
As pointed out in the "Ruby in the browser" example above, there is no
need for the eigenclass to actually exist as a regular class, let alone
have a single instance. Clearly then, the term singleton class would
only be appropriate to some implementations and would consequently be a
misnomer.

While I'm at it, the term "singleton method" is also a misnomer. The
term "singleton" derives from set theory. A singleton set is a set with
one element. As such, the GoF pattern is a perfect fit. However, there
is no singleton set anywhere in this situation (unless you get really
silly in your choice of set). You can have many instances, each with
many per-instance methods. The only appearance of the word "one" is on
one side of the cardinality of an association (and not on the method
side). For reasons of symmetry, eigenmethod is a far better term.

Regards,

Danny.
Jörg W Mittag (Guest)
on 2009-05-21 00:35
(Received via mailing list)
Danny O cuiv wrote:
> There seems to be two forces contributing to this. Firstly, the
> profusion of terms (many of which are clearly misnomers) is getting out
> of hand, and is unhelpful to newcomers. Secondly, many people still
> resort to referring to MRI runtime structures when discussing semantics
> even though Ruby is now being implemented on the JVM, on the CLR, on the
> Objective-C runtime and presumably elsewhere.

Yet more runtimes: the Parrot VM (Cardinal), a modified version of the
64-Bit Gemstone Smalltalk VM (MagLev), the Flash/ActionScript Tamarin
VM (Red Sun) and the SAP NetWeaver/ABAP VM (Blue Ruby). Plus
specialized Ruby VMs (Rubinius, tinyrb).

> There is now a clear need
> to be able to discuss semantics at a sufficient level of abstraction,
> i.e. purely in terms of what is revealed by the reflection API. If there
> are any inconsistencies or anomalies revealed by the API, then this
> should be addressed directly.

Let's not forget the current ISO standardization work for Ruby.
Anybody remember Open OfficeXML? It was standardized by
reverse-engineering MS Word, exactly the way that you describe (which
is basically the way RubySpec works: reverse-engineering MRI and
YARV). In the end, it was so incredibly hard to implement that even
Microsoft itself shipped a working implementation of ODF (i.e. the
native OpenOffice.Org XML format) *before* OOXML (i.e. the native MS
Office XML format). [In fact, OOXML is widely believed to be
un-implementable, because of logical contradictions in the spec.]

We *need* a specification of Ruby's semantics, independent of MRI
and/or YARV, both for the sake of all the other implementations and
ISO Ruby.

Unfortunately, there is really only one person that could write such a
spec.

Ideally, of course, that specification would be both formal and
abstract enough, so that we can automatically generate an interpreter
from it, or at least a testsuite. Or feed it to an automatic theorem
prover, and have it prove interesting properties like memory safety,
$SAFE-level safety, consistency etc.

And now, I'm going down to the stables to feed my unicorn :-)

> The central point that I think should be made here is that per-instance
> behaviour has nothing to do with inheritance, per se. One obvious
> language rule will be that per-instance behaviour should take precedence
> over instance-common behaviour and one convenient way of implementing
> that is to snap an eigenclass into the chain between the instance and
> its class. But that implementation-specific runtime structure won't
> serve as a definition of the semantics for implementations that work
> differently. Take, for example, a "Ruby in the browser" (perhaps one
> already exists?) that translates onto the JavaScript object model.

HotRuby was (is?) an implementation of not "Ruby in the browser" but
"YARV in the browser". It was basically a YARV bytecode interpreter
loop written in JavaScript (meaning it requires that the Ruby
sourcecode gets pre-compiled with the actual YARV compiler, the
bytecode dumped to disk and then delivered to the browser as a binary
blob).

YARI (Yet Another Ruby Interpreter) aka IoRuby was an implementation
of Ruby (1.6, I think – it was before my time) on the Io runtime in
Io, which is a prototype-based OO language.

There has been talk about implementing Ruby on top of V8, which is an
ECMAScript engine.

There has been talk about implementing Ruby on top of NekoVM, which
has a unified class/prototype model.

None of these implementations actually have come even close to doing
anything even remotely useful and of course couldn't even dream of
running (let alone *passing*) RubySpec. But, there is at least *some*
interest in running Ruby on top of "prototype-ish" runtimes.

jwm
This topic is locked and can not be replied to.