Это легко воспроизвести с помощью 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"
Как вы заявили, вы получаете этот симптом только в разработке. Когда Rails перезагружает классы, он просто вызывает remove_const
для определенных классов, чтобы заставить их перезагружаться (используя autoload
). Вот код . На самом деле Rails будет вызывать DynamicFieldsets::Field.before_remove_const
, если он определен, как объяснено здесь , как хорошо: -)
Это должен быть сборщик мусора, и вы можете запустить GC с помощью GC.start
, но если у вас есть экземпляры старых классов (например, first_x
в моем примере) или подклассов, старые классы не могут быть мусором собраны.
Обратите внимание, что is_a?
должно работать нормально, в том смысле, что новые экземпляры будут kind_of?
и is_a?
нового класса. В моем примере:
first_x.is_a? X # => false
second_x.is_a? X # => true
Это правильное поведение, поскольку X
относится к новому классу, а не к старому классу.