2016-10-31 83 views
5

有這樣的一個類。如何獲得沒有命名空間的只有類名

module Foo 
    class Bar 
    end 
end 

而且我想要得到的Bar類名沒有Foo

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

我可以通過此代碼獲取類名,但我不認爲這是獲取它的最佳方式。

有沒有更好的方法來獲得沒有命名空間的類的名稱?

+1

_Sidenote_:你的正則表達式將產生'美孚::酒吧:: Baz'和具有兩個多嵌套級的任何類錯誤的結果。 – mudasobwa

回答

6

執行此操作的規範方法是調用Object#classModule#name。例如:

bar.class.name.split('::').last 
#=> "Bar" 
2

我相信這會工作太細:

module Foo 
    class Bar 
    end 
end 

bar = Foo::Bar.new 

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

這將導致

Bar 

我也相信這將是一個有點比正則表達式評價更快,但我不肯定這一點,我沒有執行基準。

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。也許你想縮小這clases其名稱以"Bar"

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

如果你想排除「富::」(雖然我不能想象爲什麼)名稱的一部分,這是一個簡單的字符串操作:

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

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

注意有沒有對象BarGoo::Bar