Skip to content
This repository
Browse code

Update Object.subclasses_of to locate nested classes. Update Object.r…

…emove_subclasses_of to use Class.remove_class.

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@4049 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
  • Loading branch information...
commit 3bab575316d919d1d51b9384f76f73cbcb0971e9 1 parent 4238666
Nicholas Seckar authored March 26, 2006
4  activesupport/CHANGELOG
... ...
@@ -1,5 +1,9 @@
1 1
 *SVN*
2 2
 
  3
+* Update Object.subclasses_of to locate nested classes. This affects Object.remove_subclasses_of in that nested classes will now be unloaded. [Nicholas Seckar]
  4
+
  5
+* Update Object.remove_subclasses_of to use Class.remove_class, reducing duplication. [Nicholas Seckar]
  6
+
3 7
 * Added Fixnum#seconds for consistency, so you can say 5.minutes + 30.seconds instead of 5.minutes + 30 #4389 [François Beausoleil]
4 8
 
5 9
 * Added option to String#camelize to generate lower-cased camel case by passing in :lower, like "super_man".camelize(:lower) # => "superMan" [DHH]
11  activesupport/lib/active_support/core_ext/object/extending.rb
... ...
@@ -1,14 +1,17 @@
1 1
 class Object #:nodoc:
2 2
   def remove_subclasses_of(*superclasses)
3  
-    subclasses_of(*superclasses).each do |subclass|
4  
-      Object.send(:remove_const, subclass.to_s) rescue nil
5  
-    end
  3
+    Class.remove_class(*subclasses_of(*superclasses))
6 4
   end
7 5
 
8 6
   def subclasses_of(*superclasses)
9 7
     subclasses = []
10 8
     ObjectSpace.each_object(Class) do |k|
11  
-      next if (k.ancestors & superclasses).empty? || superclasses.include?(k) || k.to_s.include?("::") || subclasses.include?(k) || !Object.const_defined?(k.to_s.to_sym)
  9
+      next if # Exclude this class if
  10
+        (k.ancestors & superclasses).empty? || # It's not a subclass of our supers
  11
+        superclasses.include?(k) || # It *is* one of the supers
  12
+        subclasses.include?(k) || # We already have it for some obscure reason
  13
+        eval("! defined?(::#{k})") || # It's not defined.
  14
+        eval("::#{k}").object_id != k.object_id
12 15
       subclasses << k
13 16
     end
14 17
     subclasses
27  activesupport/test/core_ext/object_and_class_ext_test.rb
@@ -10,6 +10,13 @@ class ClassD < ClassA; end
10 10
 class ClassI; end
11 11
 class ClassJ < ClassI; end
12 12
 
  13
+class ClassK
  14
+end
  15
+module Nested
  16
+  class ClassL < ClassK
  17
+  end
  18
+end
  19
+
13 20
 module Bar
14 21
   def bar; end
15 22
 end
@@ -40,6 +47,22 @@ def test_subclasses_of
40 47
     ClassI.remove_subclasses
41 48
     assert_equal [], Object.subclasses_of(ClassI)
42 49
   end
  50
+  
  51
+  def test_subclasses_of_should_find_nested_classes
  52
+    assert Object.subclasses_of(ClassK).include?(Nested::ClassL)
  53
+  end
  54
+  
  55
+  def test_subclasses_of_should_not_return_removed_classes
  56
+    # First create the removed class
  57
+    old_class = Nested.send :remove_const, :ClassL
  58
+    new_class = Class.new(ClassK)
  59
+    Nested.const_set :ClassL, new_class
  60
+    assert_equal "Nested::ClassL", new_class.name # Sanity check
  61
+    
  62
+    subclasses = Object.subclasses_of(ClassK)
  63
+    assert subclasses.include?(new_class)
  64
+    assert ! subclasses.include?(old_class)
  65
+  end
43 66
 end
44 67
 
45 68
 class ObjectTests < Test::Unit::TestCase
@@ -55,9 +78,9 @@ def test_suppress_supresses
55 78
  
56 79
   def test_extended_by
57 80
     foo = Foo.new
58  
-    assert_equal [Bar], foo.extended_by
  81
+    assert foo.extended_by.include?(Bar)
59 82
     foo.extend(Baz)
60  
-    assert_equal %w(Bar Baz), foo.extended_by.map {|mod| mod.name}.sort
  83
+    assert ([Bar, Baz] - foo.extended_by).empty?, "Expected Bar, Baz in #{foo.extended_by.inspect}"
61 84
   end
62 85
   
63 86
   def test_extend_with_included_modules_from

0 notes on commit 3bab575

Please sign in to comment.
Something went wrong with that request. Please try again.