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

Sła*_*osz 49 ruby

我有一个模块Foo,它是许多类的命名空间Foo::Bar,Foo::Baz依此类推.

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

sep*_*p2k 61

Foo.constants
Run Code Online (Sandbox Code Playgroud)

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

Foo.constants.select {|c| Foo.const_get(c).is_a? Class}
Run Code Online (Sandbox Code Playgroud)

如果您需要类和模块名称,则可以使用is_a? Module而不是is_a? Class.

  • 确保在之前加载所有类:`Dir ["app/models/foo/*.rb"].each {| file | 加载文件}` (5认同)
  • @jcaudle Ruby做*不是懒惰的加载类.你在考虑Rails. (3认同)
  • 这只适用于先前加载的类。 (2认同)

Jör*_*tag 35

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

Foo.constants.map(&Foo.method(:const_get)).grep(Class)
Run Code Online (Sandbox Code Playgroud)

  • 我爱*无点编程.我的Haskell通过了吗? (5认同)

pis*_*ruk 14

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

Foo.constants.select {|c| Foo.const_get(c).is_a? Class}
Run Code Online (Sandbox Code Playgroud)

你会得到

[]
Run Code Online (Sandbox Code Playgroud)

但输入后:

Foo::Bar
Run Code Online (Sandbox Code Playgroud)

你会得到

[:Bar]
Run Code Online (Sandbox Code Playgroud)


小智 12

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

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

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

Foo.constants.map(Foo.method(:const_get)).grep的(类)

  • 如果您在运行时检查模块,这种方法是有问题的 (2认同)