Skip to content
This repository
Browse code

Extract descendents a bit so it can take advantage of Rubinius' __sub…

…classes__.
  • Loading branch information...
commit 0f7f90d25bece35194b2d0035de8874e869d299e 1 parent 25bb301
Yehuda Katz authored
6 activesupport/lib/active_support/core_ext/class/removal.rb
@@ -2,7 +2,11 @@
2 2 require 'active_support/core_ext/module/introspection'
3 3
4 4 class Class #:nodoc:
5   -
  5 +
  6 + def reachable?
  7 + eval("defined?(::#{self}) && ::#{self}.equal?(self)")
  8 + end
  9 +
6 10 # Unassociates the class with its subclasses and removes the subclasses
7 11 # themselves.
8 12 #
73 activesupport/lib/active_support/core_ext/object/extending.rb
... ... @@ -1,46 +1,53 @@
1   -class Object
2   - def remove_subclasses_of(*superclasses) #:nodoc:
3   - Class.remove_class(*subclasses_of(*superclasses))
4   - end
5   -
6   - begin
7   - ObjectSpace.each_object(Class.new) {}
8   -
9   - # Exclude this class unless it's a subclass of our supers and is defined.
10   - # We check defined? in case we find a removed class that has yet to be
11   - # garbage collected. This also fails for anonymous classes -- please
12   - # submit a patch if you have a workaround.
13   - def subclasses_of(*superclasses) #:nodoc:
  1 +class Class
  2 + # Rubinius
  3 + if defined?(Class.__subclasses__)
  4 + def descendents
14 5 subclasses = []
15   -
16   - superclasses.each do |sup|
17   - ObjectSpace.each_object(class << sup; self; end) do |k|
18   - if k != sup && (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
19   - subclasses << k
20   - end
21   - end
22   - end
23   -
  6 + __subclasses__.each {|k| subclasses << k; subclasses.concat k.descendents }
24 7 subclasses
25 8 end
26   - rescue RuntimeError
27   - # JRuby and any implementations which cannot handle the objectspace traversal
28   - # above fall back to this implementation
29   - def subclasses_of(*superclasses) #:nodoc:
30   - subclasses = []
  9 + else
  10 + # MRI
  11 + begin
  12 + ObjectSpace.each_object(Class.new) {}
31 13
32   - superclasses.each do |sup|
  14 + def descendents
  15 + subclasses = []
  16 + ObjectSpace.each_object(class << self; self; end) do |k|
  17 + subclasses << k unless k == self
  18 + end
  19 + subclasses
  20 + end
  21 + # JRuby
  22 + rescue StandardError
  23 + def descendents
  24 + subclasses = []
33 25 ObjectSpace.each_object(Class) do |k|
34   - if superclasses.any? { |superclass| k < superclass } &&
35   - (k.name.blank? || eval("defined?(::#{k}) && ::#{k}.object_id == k.object_id"))
36   - subclasses << k
37   - end
  26 + subclasses << k if k < self
38 27 end
39 28 subclasses.uniq!
  29 + subclasses
40 30 end
41   - subclasses
42 31 end
43 32 end
  33 +end
  34 +
  35 +class Object
  36 + def remove_subclasses_of(*superclasses) #:nodoc:
  37 + Class.remove_class(*subclasses_of(*superclasses))
  38 + end
  39 +
  40 + # Exclude this class unless it's a subclass of our supers and is defined.
  41 + # We check defined? in case we find a removed class that has yet to be
  42 + # garbage collected. This also fails for anonymous classes -- please
  43 + # submit a patch if you have a workaround.
  44 + def subclasses_of(*superclasses) #:nodoc:
  45 + subclasses = []
  46 + superclasses.each do |klass|
  47 + subclasses.concat klass.descendents.select {|k| k.name.blank? || k.reachable?}
  48 + end
  49 + subclasses
  50 + end
44 51
45 52 def extended_by #:nodoc:
46 53 ancestors = class << self; ancestors end

0 comments on commit 0f7f90d

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