Project

General

Profile

Backport #4273

Updated by jeremyevans0 (Jeremy Evans) over 5 years ago

=begin 
  
  class Base 
    def self.inherited(klass) 
      klass.instance_variable_set(:@x, :base) 
    end 
  end 
 
  Derived = Class.new(Base) do 
              @x = :derived 
            end 
 
  # BUG HERE! 
  Derived.instance_variable_get(:@x) #=> :base 
 
  In Ruby 1.9 the line above returns :derived. Ruby 1.9 has the expected behaviour as the inherited hook should be invoked prior to running the block -- so that the block can override any ivar defaults defined by the inherited hook. 
 
  The problem lies in the following code, from object.c: 
 
 
  static VALUE 
  rb_class_initialize(argc, argv, klass) 
      int argc; 
      VALUE *argv; 
      VALUE klass; 
  { 
      VALUE super; 
 
      if (RCLASS(klass)->super != 0) { 
 	 rb_raise(rb_eTypeError, "already initialized class"); 
      } 
      if (rb_scan_args(argc, argv, "01", &super) == 0) { 
 	 super = rb_cObject; 
      } 
      else { 
 	 rb_check_inheritable(super); 
      } 
      RCLASS(klass)->super = super; 
      rb_make_metaclass(klass, RBASIC(super)->klass); 
  *      rb_mod_initialize(klass); 
  *      rb_class_inherited(super, klass); 
 
      return klass; 
  } 
 
  The fix would be simple, just swap the two starred lines above. 
 
  thanks, 
 
  John 
 
 =end 
 

Back