Class#descendants

Ruby provides a Module#ancestors, but no Class#descendants.

Here’s what you can do to keep track of your own subclasses:

module DescendantsMixin
  def inherited(klass)
    subclasses << klass
  end

  def subclasses
    @subclasses ||= []
  end

  def descendants
    subclasses.inject(subclasses) do |all, subclass|
      all + subclass.descendants
    end
  end
end

class A
  extend DescendantsMixin
end

class B < A; end
class C < B; end

A.subclasses  # => [B]
A.descendants # => [B, C]

See Also

Ruby Facets provides a Class#descendents that uses ObjectSpace instead of Class#inherited.