7

Is there a way to get the list of all defined classes. I'm looking for a code like this:

Class.instances.each do |klass|
  puts klass.name
end

If there is no way to do this. It is possible to define a class A such that its descendants are registered in it? For example in this way:

class A
  ...
end

class B < A
end

class C < B
end

A.descendants   # => [B, C] 
Daniel Hernández
  • 1,279
  • 8
  • 15

3 Answers3

6

The ObjectSpace can help you get all instances of a class. This will thus return all defined classes

ObjectSpace.each_object(Class)
gmalette
  • 2,439
  • 17
  • 26
  • 2
    It will, however, also return classes that once were defined but aren't any longer, but haven't yet been garbage collected. – Jörg W Mittag Apr 06 '13 at 15:35
5
p ObjectSpace.each_object(Class){|ob| p ob}
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • Your first solution won’t work, as `constants` returns an array of symbols, not the actual constants. – Andrew Marshall Apr 06 '13 at 16:06
  • I know what `constants` does, but you don’t seem to. `Object.constants.grep(Class).empty? #=> true`, thus your `each` is useless. – Andrew Marshall Apr 06 '13 at 16:17
  • `ob` will *never* be an instance of Class. This means that you include things that are not classes in your list since you never filter them. I’m not trying to be rude, but you’re pointing me to documentation that shows that what you’re doing doesn’t work as you expect. – Andrew Marshall Apr 06 '13 at 16:19
  • Just because there’s output doesn’t mean it’s correct… which it’s not. – Andrew Marshall Apr 06 '13 at 16:26
  • @AndrewMarshall you are correct! updated. – Arup Rakshit Apr 06 '13 at 16:35
2

In addition to ObjectSpace, a smart hook method you can define is inherited, which Ruby will invoke every time its class is subclassed.

class A
  @sub_classes = []

  def self.inherited(sub_class)
    @sub_classes << sub_class
  end
end
osahyoun
  • 5,173
  • 2
  • 17
  • 15