calling a 'class' method on an object's metaclass should invoke the class method of the object's class
Reported by Sam Aaron | June 22nd, 2008 @ 01:50 AM | in 1.0 preview
Try executing the attached file (created to aid my understanding of Ruby's object model). In Rubinius it fails at the following line:
puts "b_with_meta.metaclass.cheese: #{b_with_meta.metaclass.cheese}"
However, on all other versions of Ruby (MRI, JRuby, MacRuby, Ruby-1-9), the code executes completely and produces the following output:
A.cheese: edam
B.cheese: stilton
a.cheese: shropshire blue
b.cheese: cheddar
b_with_meta.cheese: cheshire
b_with_meta.metaclass.cheese: stilton
b_with_meta_meta.cheese: brie
b_with_meta_meta.metaclass.cheese: gouda
b_with_meta_meta.metaclass.metaclass.cheese: wensleydale
Comments and changes to this ticket
-
Ryan Davis June 23rd, 2008 @ 03:50 PM
- → Assigned user changed from to Wilson Bilkovich
-
Sam Aaron October 29th, 2008 @ 03:53 AM
- → Tag changed from to bug
This seems to be fixed with the new C++ VM.
-
-
Lin Jen-Shin December 4th, 2008 @ 01:35 AM
I think this relate to the construction of ruby object model. As far as I know, it's correct in current Rubinius object model. 'stilton' was defined in B's metaclass, and can be called from B, and B's subclasses. But not in b's metaclass, it's the place for b's singleton method only.
I am wondering why MRI and JRuby would yield this result. Perhaps they have a little different object model in this place.
-
Lin Jen-Shin December 4th, 2008 @ 01:57 AM
here's minimum weirdness:
b's metaclass changed after meta_def was called in MRI, JRuby, and b's metaclass' superclass was B's metaclass in MRI, JRuby.
@@@ Ruby class Object # The hidden singleton lurks behind everyone def metaclass; class << self; self; end; end def meta_eval(&blk)
metaclass.instance_eval(&blk)end
# Adds methods to a metaclass def meta_def name, &blk
meta_eval { define_method name, &blk }end end
class B end
b = B.new
false in Rubinius, true in MRI, JRuby
p b.metaclass.superclass.object_id == B.metaclass.object_id
b.meta_def(:cheese) {'cheshire'}
false in all implementation
p b.metaclass.superclass.object_id == B.metaclass.object_id
-

Charles L December 4th, 2008 @ 03:29 AM
I think this kind of makes sense, because defining a method on b's metaclass, requires that b's metaclass have a metaclass of its own, which is created lazily.
Before defining the method on the meta class, b.metaclass.superclass.inspect (on mri) is #<Class:B>, and after it becomes #<Class:#<Class:#<B:0xb7c1a84c>>>, ie a meta-meta class.
Note that the assertion "B.metaclass === b.metaclass.superclass" remains true before & after.
Please Login or create a free account to add a new comment.
You can update this ticket by sending an email to from your email client. (help)
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
