banister / remix

Ruby modules re-mixed and remastered
32 stars 1 forks source link

temp_extend breaks the Class #13

Open ghazel opened 13 years ago

ghazel commented 13 years ago

ruby 1.8.7 p249

This was the Rails bug I mentioned on IRC, but it turns out it's fully reproducible without Rails at all. The instance and class methods mimic a piece of class_inheritable_accessor and still demonstrate the problem.

require 'remix'

class Foo
  def self.cls_bar
    1
  end

  def inst_bar
    self.class.cls_bar
  end
end

module Nothing
end

f = Foo.new
p f.inst_bar
f.temp_extend(Nothing) do
  p f.inst_bar
end
p f.inst_bar

results in:

1
1
wtf.rb:9:in `inst_bar': undefined method `cls_bar' for Object:Class (NoMethodError)
        from wtf.rb:21
banister commented 13 years ago

This is due to Object#class using rb_class_real(). Since i turn the entire inheritance chain into iclasses the original class will no longer be a real class according to this test and so self.class will return Object instead of the actual class.

There are two ways to fix this: (1) prevent remix from turning classes into iclasses unless it really has to. (2) patch the Object#class method so it accepts iclasses inserted by remix as valid classes.