diff options
-rw-r--r-- | activesupport/CHANGELOG | 2 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/object_and_class.rb | 18 | ||||
-rw-r--r-- | activesupport/lib/active_support/dependencies.rb | 2 | ||||
-rw-r--r-- | activesupport/test/core_ext/object_and_class_ext_test.rb | 30 |
4 files changed, 40 insertions, 12 deletions
diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index b72d2fd5ed..0afb5f62b1 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,6 +1,6 @@ *SVN* -* Remove fix against memory leaks in development mode as it killed development performance on large applications (2-3s stall on Basecamp). Octopod is working on a better fix. +* Added more efficient implementation of the development mode reset of classes #1638 [Chris McGrath] *1.1.0* diff --git a/activesupport/lib/active_support/core_ext/object_and_class.rb b/activesupport/lib/active_support/core_ext/object_and_class.rb index bd67b3d1fa..4ad13265d7 100644 --- a/activesupport/lib/active_support/core_ext/object_and_class.rb +++ b/activesupport/lib/active_support/core_ext/object_and_class.rb @@ -1,9 +1,9 @@ class Object #:nodoc: - def remove_subclasses_of(superclass) - subclasses_of(superclass).each do |subclass| - # remove_instance_variables_of(klass) - Object.send(:remove_const, subclass) rescue nil - end + def remove_subclasses_of(*superclasses) + subclasses_of(*superclasses).each do |subclass| + subclass.instance_variables.each { |v| subclass.send(:remove_instance_variable, v) } + Object.send(:remove_const, subclass.to_s) rescue nil + end end def remove_instance_variables_of(klass) @@ -14,11 +14,11 @@ class Object #:nodoc: end end - def subclasses_of(superclass) + def subclasses_of(*superclasses) subclasses = [] ObjectSpace.each_object(Class) do |k| - next if !k.ancestors.include?(superclass) || superclass == k || k.to_s.include?("::") || subclasses.include?(k.to_s) - subclasses << k.to_s + next if (k.ancestors & superclasses).empty? || superclasses.include?(k) || k.to_s.include?("::") || subclasses.include?(k) + subclasses << k end subclasses end @@ -50,6 +50,6 @@ class Class #:nodoc: end def subclasses - Object.subclasses_of(self) + Object.subclasses_of(self).map { |o| o.to_s } end end diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index bb46087582..c37e868b83 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -39,7 +39,7 @@ module Dependencies #:nodoc: end def remove_subclasses_for(*classes) - classes.each { |klass| klass.remove_subclasses } + Object.remove_subclasses_of(*classes) end # LoadingModules implement namespace-safe dynamic loading. diff --git a/activesupport/test/core_ext/object_and_class_ext_test.rb b/activesupport/test/core_ext/object_and_class_ext_test.rb index cf75159575..29b2f2fc8b 100644 --- a/activesupport/test/core_ext/object_and_class_ext_test.rb +++ b/activesupport/test/core_ext/object_and_class_ext_test.rb @@ -12,6 +12,20 @@ class RemoveSubsBaseClass end end class RemoveSubsSubClass < RemoveSubsBaseClass; end +class RemoveSubsTestClass2; end +class RemoveSubsBaseClass2 + def self.add_ivar + @ivar = RemoveSubsTestClass2.new + end +end +class RemoveSubsSubClass2 < RemoveSubsBaseClass2; end +class RemoveSubsTestClass3; end +class RemoveSubsBaseClass3 + def self.add_ivar + @ivar = RemoveSubsTestClass3.new + end +end +class RemoveSubsSubClass3 < RemoveSubsBaseClass3; end class ClassExtTest < Test::Unit::TestCase def test_methods @@ -48,4 +62,18 @@ class ObjectTests < Test::Unit::TestCase flunk("ObjectSpace still contains RemoveSubsTestClass") if o.class == RemoveSubsTestClass end end -end
\ No newline at end of file + + def test_remove_subclasses_of_multiple_classes_unsets_ivars + r2 = RemoveSubsSubClass2.new + RemoveSubsSubClass2.add_ivar + r3 = RemoveSubsSubClass3.new + RemoveSubsSubClass3.add_ivar + + Object.remove_subclasses_of(RemoveSubsBaseClass2, RemoveSubsBaseClass3) + + GC.start + ObjectSpace.each_object do |o| + flunk("ObjectSpace still contains RemoveSubsTestClass") if o.class == RemoveSubsTestClass + end + end +end |