subclasses.rb 1.3 KB
Newer Older
1
# frozen_string_literal: true
2

3
class Class
4
  begin
5 6
    # Test if this Ruby supports each_object against singleton_class
    ObjectSpace.each_object(Numeric.singleton_class) {}
7

8 9 10 11 12 13 14 15 16 17 18 19 20 21
    # Returns an array with all classes that are < than its receiver.
    #
    #   class C; end
    #   C.descendants # => []
    #
    #   class B < C; end
    #   C.descendants # => [B]
    #
    #   class A < B; end
    #   C.descendants # => [B, A]
    #
    #   class D < C; end
    #   C.descendants # => [B, A, D]
    def descendants
22
      descendants = []
23
      ObjectSpace.each_object(singleton_class) do |k|
24
        next if k.singleton_class?
25
        descendants.unshift k unless k == self
26 27
      end
      descendants
28
    end
29
  rescue StandardError # JRuby 9.0.4.0 and earlier
30
    def descendants
31 32 33
      descendants = []
      ObjectSpace.each_object(Class) do |k|
        descendants.unshift k if k < self
34
      end
35 36
      descendants.uniq!
      descendants
37
    end
38
  end
39

40 41
  # Returns an array with the direct children of +self+.
  #
42 43
  #   class Foo; end
  #   class Bar < Foo; end
44
  #   class Baz < Bar; end
45
  #
46
  #   Foo.subclasses # => [Bar]
47 48 49 50
  def subclasses
    subclasses, chain = [], descendants
    chain.each do |k|
      subclasses << k unless chain.any? { |c| c > k }
51
    end
52
    subclasses
53 54
  end
end