ruby namespaces

ruby - Cómo obtener solo el nombre de la clase sin espacio de nombres



namespaces (4)

Hay una clase como esta.

module Foo class Bar end end

Y quiero obtener el nombre de clase de Bar sin Foo .

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

Podría obtener el nombre de la clase con este código, pero no creo que esta sea la mejor manera de obtenerlo.

¿Hay una mejor manera de obtener el nombre de clase sin espacio de nombres?


Creo que esto también funcionaría bien:

module Foo class Bar end end bar = Foo::Bar.new print bar.class.to_s.split(''::'').last

Esto daría lugar a

Bar

También creo que sería un poco más rápido que la evaluación de expresiones regulares, pero no estoy seguro de esto y no he realizado un punto de referencia.


La forma canónica de hacer esto es invocar Object#class y Module#name . Por ejemplo:

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



Supongamos que tenemos el siguiente módulo Foo :

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

Si no sabe qué clases están contenidas en Foo , puede hacer lo siguiente:

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]

Ver ObjectSpace::each_object .

A continuación, puede hacer lo que desee con la matriz a . Quizás quieras limitar esto a las clases cuyos nombres terminan con "Bar" :

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

Si quieres la parte de los nombres que excluye "Foo ::" (aunque no puedo imaginar por qué), es una simple manipulación de cadena:

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

o

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

Tenga en cuenta que no hay una Bar objetos o Goo::Bar .