diff options
author | Yehuda Katz <wycats@Yehuda-Katz.local> | 2009-12-13 06:29:50 -0500 |
---|---|---|
committer | Yehuda Katz <wycats@Yehuda-Katz.local> | 2009-12-13 10:39:10 -0500 |
commit | 0f7f90d25bece35194b2d0035de8874e869d299e (patch) | |
tree | 62e732b0022b50c177e7c9288c7d7f8a63c6b5e8 /activesupport | |
parent | 25bb301d9c392d7c38ac8e6f5b64ed64e7b95022 (diff) | |
download | rails-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.rb | 6 | ||||
-rw-r--r-- | activesupport/lib/active_support/core_ext/object/extending.rb | 73 |
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 |