Find every subclass of an object. Limit the query to direct descendants by setting direct to true.
1
2 require 'test/unit'
3
4 class Object
5 def self.subclasses(direct = false)
6 classes = []
7 if direct
8 ObjectSpace.each_object(Class) do |c|
9 next unless c.superclass == self
10 classes << c
11 end
12 else
13 ObjectSpace.each_object(Class) do |c|
14 next unless c.ancestors.include?(self) and (c != self)
15 classes << c
16 end
17 end
18 classes
19 end
20 end
21
22 class TrackSubclassesTest < Test::Unit::TestCase
23
24 class A; end
25 class B < A; end
26 class C < B; end
27 class D < A; end
28 class E; end
29 class F < E; end
30
31 def test_subclasses
32 assert_equal [F], E.subclasses
33 assert_equal [C], B.subclasses
34 assert_equal [B, D], A.subclasses(true).sort_by { |c| c.name }
35 assert_equal [B, C, D], A.subclasses.sort_by { |c| c.name }
36 end
37
38 end