#614 new
Sam Aaron

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

    Ryan Davis June 23rd, 2008 @ 03:50 PM

    • → Assigned user changed from “” to “Wilson Bilkovich”
  • Sam Aaron

    Sam Aaron October 29th, 2008 @ 03:53 AM

    • → Tag changed from “” to “bug”

    This seems to be fixed with the new C++ VM.

  • Brian Ford

    Brian Ford December 3rd, 2008 @ 11:09 PM

    It is still broken in the C++ VM.

  • Lin Jen-Shin

    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

    Lin Jen-Shin December 4th, 2008 @ 01:57 AM

    here's minimum weirdness:

    http://gist.github.com/31903

    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

    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 »

Attachments

Tags