From 3bab575316d919d1d51b9384f76f73cbcb0971e9 Mon Sep 17 00:00:00 2001 From: Nicholas Seckar Date: Sun, 26 Mar 2006 20:00:40 +0000 Subject: Update Object.subclasses_of to locate nested classes. Update Object.remove_subclasses_of to use Class.remove_class. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4049 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activesupport/CHANGELOG | 4 ++++ .../active_support/core_ext/object/extending.rb | 11 +++++---- .../test/core_ext/object_and_class_ext_test.rb | 27 ++++++++++++++++++++-- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/activesupport/CHANGELOG b/activesupport/CHANGELOG index 7978626fe6..9852e4a5fb 100644 --- a/activesupport/CHANGELOG +++ b/activesupport/CHANGELOG @@ -1,5 +1,9 @@ *SVN* +* Update Object.subclasses_of to locate nested classes. This affects Object.remove_subclasses_of in that nested classes will now be unloaded. [Nicholas Seckar] + +* Update Object.remove_subclasses_of to use Class.remove_class, reducing duplication. [Nicholas Seckar] + * Added Fixnum#seconds for consistency, so you can say 5.minutes + 30.seconds instead of 5.minutes + 30 #4389 [François Beausoleil] * Added option to String#camelize to generate lower-cased camel case by passing in :lower, like "super_man".camelize(:lower) # => "superMan" [DHH] diff --git a/activesupport/lib/active_support/core_ext/object/extending.rb b/activesupport/lib/active_support/core_ext/object/extending.rb index 9abdfc0bc9..16f62d85b7 100644 --- a/activesupport/lib/active_support/core_ext/object/extending.rb +++ b/activesupport/lib/active_support/core_ext/object/extending.rb @@ -1,14 +1,17 @@ class Object #:nodoc: def remove_subclasses_of(*superclasses) - subclasses_of(*superclasses).each do |subclass| - Object.send(:remove_const, subclass.to_s) rescue nil - end + Class.remove_class(*subclasses_of(*superclasses)) end def subclasses_of(*superclasses) subclasses = [] ObjectSpace.each_object(Class) do |k| - next if (k.ancestors & superclasses).empty? || superclasses.include?(k) || k.to_s.include?("::") || subclasses.include?(k) || !Object.const_defined?(k.to_s.to_sym) + next if # Exclude this class if + (k.ancestors & superclasses).empty? || # It's not a subclass of our supers + superclasses.include?(k) || # It *is* one of the supers + subclasses.include?(k) || # We already have it for some obscure reason + eval("! defined?(::#{k})") || # It's not defined. + eval("::#{k}").object_id != k.object_id subclasses << k end subclasses 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 6a100e813b..a1e5ea79db 100644 --- a/activesupport/test/core_ext/object_and_class_ext_test.rb +++ b/activesupport/test/core_ext/object_and_class_ext_test.rb @@ -10,6 +10,13 @@ class ClassD < ClassA; end class ClassI; end class ClassJ < ClassI; end +class ClassK +end +module Nested + class ClassL < ClassK + end +end + module Bar def bar; end end @@ -40,6 +47,22 @@ class ClassExtTest < Test::Unit::TestCase ClassI.remove_subclasses assert_equal [], Object.subclasses_of(ClassI) end + + def test_subclasses_of_should_find_nested_classes + assert Object.subclasses_of(ClassK).include?(Nested::ClassL) + end + + def test_subclasses_of_should_not_return_removed_classes + # First create the removed class + old_class = Nested.send :remove_const, :ClassL + new_class = Class.new(ClassK) + Nested.const_set :ClassL, new_class + assert_equal "Nested::ClassL", new_class.name # Sanity check + + subclasses = Object.subclasses_of(ClassK) + assert subclasses.include?(new_class) + assert ! subclasses.include?(old_class) + end end class ObjectTests < Test::Unit::TestCase @@ -55,9 +78,9 @@ class ObjectTests < Test::Unit::TestCase def test_extended_by foo = Foo.new - assert_equal [Bar], foo.extended_by + assert foo.extended_by.include?(Bar) foo.extend(Baz) - assert_equal %w(Bar Baz), foo.extended_by.map {|mod| mod.name}.sort + assert ([Bar, Baz] - foo.extended_by).empty?, "Expected Bar, Baz in #{foo.extended_by.inspect}" end def test_extend_with_included_modules_from -- cgit v1.2.3