How to get only class name without namespace

There is such a class.

module Foo class Bar end end 

And I want to get the class name Bar without Foo .

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

I could get the class name from this code, but I don't think this is the best way to get it.

Is there a better way to get a class name without a namespace?

+6
source share
4 answers

The canonical way to do this is to call the object class # and Module # name . For instance:

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

If you use Rails, you can actually use the demodulize method in the String class. http://apidock.com/rails/String/demodulize

 bar.class.name.demodulize 
+11
source

I believe this will work well too:

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

This will lead to

 Bar 

I also believe that it will be a little faster than evaluating regular expressions, but I'm not sure about it, and I did not complete the benchmark.

+2
source

Suppose we have the following Foo module:

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

If you don't know what classes are in Foo , you can do the following:

 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] 

See ObjectSpace :: each_object .

Then you can do what you want with the array a . Perhaps you want to narrow it down to treasures whose names end in "Bar" :

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

If you want some of the names to exclude "Foo ::" (although I can't imagine why), this is a simple string manipulation:

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

or

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

Please note: there is no Bar or Goo::Bar object.

+1
source

Source: https://habr.com/ru/post/1011873/


All Articles