2016-10-31 4 views
5

Es gibt eine Klasse wie diese.Wie erhält man nur Klassennamen ohne Namensraum

module Foo 
    class Bar 
    end 
end 

Und ich will den Klassennamen Bar ohne Foo bekommen.

Ich könnte den Klassennamen mit diesem Code erhalten, aber ich denke nicht, dass dies der beste Weg ist, um es zu bekommen.

Gibt es bessere Möglichkeit, den Namen der Klasse ohne Namespace zu erhalten?

+1

_Sidenote_: Ihr regexp wird falsches Ergebnis erzeugen auf 'Foo :: Bar :: Baz' und jede Klasse zwei und mehr Verschachtelungsebene aufweist. – mudasobwa

Antwort

6

Der kanonische Weg, dies zu tun, ist Object#class und Module#name aufrufen. Zum Beispiel:

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

Ich glaube, das würde funktionieren auch:

module Foo 
    class Bar 
    end 
end 

bar = Foo::Bar.new 

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

Dies würde in

Bar 

Ich glaube auch, es wäre ein bisschen schneller als die regulären Ausdruck Auswertung sein, aber ich bin nicht sicher darüber und ich habe keine Benchmark durchgeführt.

1

Angenommen, wir haben das folgende Modul Foo:

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

Wenn Sie nicht wissen, welche Klassen in Foo enthalten sind, können Sie Folgendes tun könnten:

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] 

Siehe ObjectSpace::each_object.

Sie können dann tun, was Sie mit dem Array a tun möchten. Vielleicht möchten Sie diese zu clases, deren Namen mit "Bar" Ende verengen:

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

Wenn Sie den Teil der Namen möchten, die „Foo ::“ schließt (obwohl ich nicht, warum sich vorstellen kann), es ist eine einfache Zeichenfolge Manipulation:

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

oder

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

Beachten Sie, dass es Bar oder Goo::Bar keine Rolle spielt.

Verwandte Themen