如何只获取没有命名空间的类名

时间:2016-10-31 05:04:58

标签: ruby namespaces

有一个这样的课程。

module Foo
  class Bar
  end
end

我希望Bar的班级名称不含Foo

bar = Foo::Bar.new
bar.class.to_s.match('::(.+)$'){ $1 }

我可以通过此代码获取课程名称,但我不认为这是获得该课程的最佳方式。

有没有更好的方法来获取没有名称空间的类的名称?

4 个答案:

答案 0 :(得分:47)

如果您正在使用Rails,您实际上可以在String类上使用demodulize方法。 http://apidock.com/rails/String/demodulize

bar.class.name.demodulize

答案 1 :(得分:11)

执行此操作的规范方法是调用Object#classModule#name。例如:

google-services.json

答案 2 :(得分:3)

我相信这也可行:

module Foo
  class Bar
  end
end

bar = Foo::Bar.new

print bar.class.to_s.split('::').last

这会导致

Bar

我也相信它会比正则表达式评估快一点,但我对此并不确定,我还没有执行基准测试。

答案 3 :(得分:1)

假设我们有以下模块Foo

module Foo
  class Bar
  end
  class Tar
  end
  module Goo
    class Bar
    end
  end
end

如果您不知道Foo中包含哪些类,您可以执行以下操作:

a = ObjectSpace.each_object(Class).with_object([]) { |k,a|
      a << k if k.to_s.start_with?("Foo::") }
  #=> [Foo::Tar, Foo::Goo::Bar, Foo::Bar]

请参阅ObjectSpace::each_object

然后,您可以使用数组a执行所需操作。也许你想把它缩小到名字以"Bar"结尾的clases:

b = a.select { |k| k.to_s.end_with?("Bar") }
  #=> [Foo::Goo::Bar, Foo::Bar]

如果你想要的名称部分排除“Foo ::”(虽然我无法想象为什么),这是一个简单的字符串操作:

b.map { |k| k.to_s["Foo::".size..-1] }
  #=> ["Goo::Bar", "Bar"]

b.map { |k| k.to_s[/(?<=\AFoo::).*/]
  #=> ["Goo::Bar", "Bar"] }

请注意,没有对象BarGoo::Bar