How to get all class names in a namespace in Ruby?

Ruby

Ruby Problem Overview


I have a module Foo, that it is the namespace for many classes like Foo::Bar, Foo::Baz and so on.

Is there an way to return all class names namespaced by Foo?

Ruby Solutions


Solution 1 - Ruby

Foo.constants

returns all constants in Foo. This includes, but is not limited to, classnames. If you want only class names, you can use

Foo.constants.select {|c| Foo.const_get(c).is_a? Class}

If you want class and module names, you can use is_a? Module instead of is_a? Class.

Solution 2 - Ruby

If, instead of the names of the constants, you want the classes themselves, you could do it like this:

Foo.constants.map(&Foo.method(:const_get)).grep(Class)

Solution 3 - Ruby

In short no. However, you can show all classes that have been loaded. So first you have to load all classfiles in the namespace:

Dir["#{File.dirname(__FILE__)}/lib/foo/*.rb"].each {|file| load file}

then you can use a method like Jörg W Mittag's to list the classes >Foo.constants.map(&Foo.method(:const_get)).grep(Class)

Solution 4 - Ruby

This will only return the loaded constants under the given namespace because ruby uses a lazy load approach. So, if you type

Foo.constants.select {|c| Foo.const_get(c).is_a? Class}

you will get

[]

but after typing:

Foo::Bar

you will get

[:Bar]

Solution 5 - Ruby

This alternative solution will load and show all classes under Foo:: including "nested" classes, e.g. Foo::Bar::Bar.

Dir["#{File.dirname(__FILE__)}/lib/foo/**/*.rb"].each { |file| load file }
ObjectSpace.each_object(Class).select { |c| c.to_s.start_with? "Foo::" }

Note: **/*.rb recursively globs.

If you want to include the Foo class itself, you could change your select to e.g. { |c| c.to_s =~ /^Foo\b/ }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSławoszView Question on Stackoverflow
Solution 1 - Rubysepp2kView Answer on Stackoverflow
Solution 2 - RubyJörg W MittagView Answer on Stackoverflow
Solution 3 - RubySilverdevView Answer on Stackoverflow
Solution 4 - RubyPikachuView Answer on Stackoverflow
Solution 5 - RubytantrixView Answer on Stackoverflow