aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorYehuda Katz <wycats@Yehuda-Katz.local>2009-12-13 06:29:50 -0500
committerYehuda Katz <wycats@Yehuda-Katz.local>2009-12-13 10:39:10 -0500
commit0f7f90d25bece35194b2d0035de8874e869d299e (patch)
tree62e732b0022b50c177e7c9288c7d7f8a63c6b5e8 /activesupport
parent25bb301d9c392d7c38ac8e6f5b64ed64e7b95022 (diff)
downloadrails-0f7f90d25bece35194b2d0035de8874e869d299e.tar.gz
rails-0f7f90d25bece35194b2d0035de8874e869d299e.tar.bz2
rails-0f7f90d25bece35194b2d0035de8874e869d299e.zip
Extract descendents a bit so it can take advantage of Rubinius' __subclasses__.
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/lib/active_support/core_ext/class/removal.rb6
-rw-r--r--activesupport/lib/active_support/core_ext/object/extending.rb73
2 files changed, 45 insertions, 34 deletions
diff --git a/activesupport/lib/active_support/core_ext/class/removal.rb b/activesupport/lib/active_support/core_ext/class/removal.rb
index 2dea3c24d5..652be4ed78 100644
--- a/activesupport/lib/active_support/core_ext/class/removal.rb
+++ b/activesupport/lib/active_support/core_ext/class/removal.rb
@@ -2,7 +2,11 @@ require 'active_support/core_ext/object/extending'
require 'active_support/core_ext/module/introspection'
class Class #:nodoc:
-
+
+ def reachable?
+ eval("defined?(::#{self}) && ::#{self}.equal?(self)")
+ end
+
# Unassociates the class with its subclasses and removes the subclasses
# themselves.
#
diff --git a/activesupport/lib/active_support/core_ext/object/extending.rb b/activesupport/lib/active_support/core_ext/object/extending.rb
index 0cc74c8298..de8121f274 100644
--- a/activesupport/lib/active_support/core_ext/object/extending.rb
+++ b/activesupport/lib/active_support/core_ext/object/extending.rb
@@ -1,46 +1,53 @@
-class Object
- def remove_subclasses_of(*superclasses) #:nodoc:
- Class.remove_class(*subclasses_of(*superclasses))
- end
-
- begin
- ObjectSpace.each_object(Class.new) {}
-
- # Exclude this class unless it's a subclass of our supers and is defined.
- # We check defined? in case we find a removed class that has yet to be
- # garbage collected. This also fails for anonymous classes -- please
- # submit a patch if you have a workaround.
- def subclasses_of(*superclasses) #:nodoc:
+class Class
+ # Rubinius
+ if defined?(Class.__subclasses__)
+ def descendents
subclasses = []
-
- superclasses.each do |sup|
- ObjectSpace.each_object(class << sup; self; end) do |k|
- if k != sup && (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
- subclasses << k
- end
- end
- end
-
+ __subclasses__.each {|k| subclasses << k; subclasses.concat k.descendents }
subclasses
end
- rescue RuntimeError
- # JRuby and any implementations which cannot handle the objectspace traversal
- # above fall back to this implementation
- def subclasses_of(*superclasses) #:nodoc:
- subclasses = []
+ else
+ # MRI
+ begin
+ ObjectSpace.each_object(Class.new) {}
- superclasses.each do |sup|
+ def descendents
+ subclasses = []
+ ObjectSpace.each_object(class << self; self; end) do |k|
+ subclasses << k unless k == self
+ end
+ subclasses
+ end
+ # JRuby
+ rescue StandardError
+ def descendents
+ subclasses = []
ObjectSpace.each_object(Class) do |k|
- if superclasses.any? { |superclass| k < superclass } &&
- (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
- subclasses << k
- end
+ subclasses << k if k < self
end
subclasses.uniq!
+ subclasses
end
- subclasses
end
end
+end
+
+class Object
+ def remove_subclasses_of(*superclasses) #:nodoc:
+ Class.remove_class(*subclasses_of(*superclasses))
+ end
+
+ # Exclude this class unless it's a subclass of our supers and is defined.
+ # We check defined? in case we find a removed class that has yet to be
+ # garbage collected. This also fails for anonymous classes -- please
+ # submit a patch if you have a workaround.
+ def subclasses_of(*superclasses) #:nodoc:
+ subclasses = []
+ superclasses.each do |klass|
+ subclasses.concat klass.descendents.select {|k| k.name.blank? || k.reachable?}
+ end
+ subclasses
+ end
def extended_by #:nodoc:
ancestors = class << self; ancestors end