如何在Ruby中的命名空间中获取所有类名?

时间:2010-09-09 11:56:42

标签: ruby

我有一个模块Foo,它是许多类的命名空间,例如Foo::BarFoo::Baz等等。

有没有办法返回Foo命名空间的所有类名?

5 个答案:

答案 0 :(得分:54)

Foo.constants

返回Foo中的所有常量。这包括但不限于类名。如果只想要类名,可以使用

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

如果您需要类和模块名称,可以使用is_a? Module代替is_a? Class

答案 1 :(得分:32)

如果你想要这些类本身,而不是常量的名称,你可以这样做:

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

答案 2 :(得分:12)

这将仅返回给定命名空间下的已加载常量,因为ruby使用延迟加载方法。 所以,如果你输入

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

你会得到

[]

但输入后:

Foo::Bar

你会得到

[:Bar]

答案 3 :(得分:11)

总之没有。但是,您可以显示已加载的所有类。 首先,您必须在命名空间中加载所有类文件:

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

然后您可以使用像JörgWMittag这样的方法来列出类

  

Foo.constants.map(安培; Foo.method(:const_get))。grep的(类)

答案 4 :(得分:0)

此替代解决方案将加载并显示 Foo:: 下的所有类,包括“嵌套”类,例如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::" }

注意:**/*.rb 递归全局。

如果您想包含 Foo 类本身,您可以将 select 更改为例如{ |c| c.to_s =~ /^Foo\b/ }