[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

meta-class subclass relationships

Greg Weeks

11/16/2007 9:20:00 AM

Ruby exposes its singleton meta-classes, eg:

class <<B ; $Meta_B = self ; end

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

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

A.new.is_a? B -> true

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

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

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

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

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

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

Should they have been true?

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

$X = $Meta_A.superclass -> #<Class:Class>
$X == $Meta_B.superclass -> true
$X == $X.superclass -> true
$X < $Meta_Object -> true
--
Posted via http://www.ruby-....

16 Answers

Greg Weeks

11/16/2007 9:42:00 AM

0

PS: I just realized that my (erroneous) expectation

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

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

Robert Dober

11/16/2007 10:08:00 AM

0

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

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

Stupid me, of course I defined a method for a

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

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

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

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

Cheers
Robert



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

Chiyuan Zhang

11/16/2007 10:10:00 AM

0

On 11?16?, ??5?20?, Greg Weeks <greg.we...@arm..com> wrote:
> FWIW: The superclass of both $Meta_A and $Meta_B is something called
> #<Class:Class>, which is its own superclass and is a subclass of
> $Meta_Object:
>
> $X = $Meta_A.superclass -> #<Class:Class>
> $X == $Meta_B.superclass -> true
> $X == $X.superclass -> true
> $X < $Meta_Object -> true
> --
> Posted viahttp://www.ruby-....

In fact, currently in ruby:

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

if you define metaclass as :

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

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

* http://whytheluckystiff.net/articles/seeingMetaclassesCl...
* http://practicalruby.blogspot.com/2007/02/ruby-metaprogramming-introdu...

David A. Black

11/16/2007 11:32:00 AM

0

Hi --

On Fri, 16 Nov 2007, Greg Weeks wrote:

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

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

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

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


David

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

David A. Black

11/16/2007 11:33:00 AM

0

Hi --

On Fri, 16 Nov 2007, Robert Dober wrote:

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

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


David

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

Paolo Nusco Perrotta

11/16/2007 11:56:00 AM

0

On Nov 16, 12:32 pm, "David A. Black" <dbl...@rubypal.com> wrote:
> It will be :-) It worked in 1.8.2, doesn't work in 1.8.6, works again
> in 1.9. I don't know what the rationale was for changing the model,
> but it's changed back.

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


Paolo Perrotta
Bologna, Italy

Rick DeNatale

11/16/2007 3:57:00 PM

0

On Nov 16, 2007 7:00 AM, Paolo Nusco Perrotta
<paolo.nusco.perrotta@gmail.com> wrote:
> On Nov 16, 12:32 pm, "David A. Black" <dbl...@rubypal.com> wrote:
> > It will be :-) 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&gr...

I notice that that bug is still marked as open.

--
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denh...

Greg Weeks

11/16/2007 7:31:00 PM

0

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

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

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

David A. Black

11/16/2007 7:52:00 PM

0

Hi --

On Sat, 17 Nov 2007, Greg Weeks wrote:

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

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


David

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

Greg Weeks

11/16/2007 9:02:00 PM

0

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

True if "real" means "non-virtual", as it so often does. But that
leaves
virtual metaclasses, at the heart of Ruby metaprogramming.
--
Posted via http://www.ruby-....