This is easy to reproduce with remove_const :
class X def self.foo "hello" end end first_x = X.new Object.send :remove_const, :X class X def self.foo "world" end end second_x = X.new p first_x.class, first_x.class.object_id, second_x.class, second_x.class.object_id # => X, <an_id>, X, <another_id> p first_x.class.foo, second_x.class.foo # => "hello", "world"
As you said, you get this symptom only in development. When Rails reloads classes, it simply calls remove_const for specific classes to force them to reload (using autoload ). Here is the code . Rails will actually call DynamicFieldsets::Field.before_remove_const if it is defined as described here , as well DynamicFieldsets::Field.before_remove_const
It should be garbage collection, and you can start GC with GC.start , but if you have instances of the old classes lying around (for example, first_x in my example) or subclasses, the old classes cannot be garbage collected.
Please note that is_a? should work fine, in the sense that new instances will be kind_of? and is_a? new class. In my example:
first_x.is_a? X # => false second_x.is_a? X # => true
This is the correct behavior, since X belongs to the new class, and not to the old class.
Marc-andrรฉ lafortune
source share