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"
Si está utilizando Rails, puede usar el método de demodulize
en la clase String. http://apidock.com/rails/String/demodulize
bar.class.name.demodulize
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
.