Permalink
Browse files

Performance: faster Object.subclasses_of

  • Loading branch information...
1 parent 88ff9e1 commit 0a11165cdc8de33c73ba5c9ee3196eed9489879c @jeremy jeremy committed Jun 8, 2008
@@ -3,17 +3,18 @@ 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 = []
- # 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.
- 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
+ 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
@@ -38,9 +38,9 @@ def test_retrieving_subclasses
@parent = eval("class D; end; D")
@sub = eval("class E < D; end; E")
@subofsub = eval("class F < E; end; F")
- assert @parent.subclasses.all? { |i| [@sub.to_s, @subofsub.to_s].include?(i) }
assert_equal 2, @parent.subclasses.size
assert_equal [@subofsub.to_s], @sub.subclasses
assert_equal [], @subofsub.subclasses
+ assert_equal [@sub.to_s, @subofsub.to_s].sort, @parent.subclasses.sort
end
end

0 comments on commit 0a11165

Please sign in to comment.