How to get only class name without namespace

RubyNamespaces

Ruby Problem Overview


There is a class like this.

module Foo
  class Bar
  end
end

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

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

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

Is there better way to get the name of class without namespace?

Ruby Solutions


Solution 1 - Ruby

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

bar.class.name.demodulize

Solution 2 - Ruby

The canonical way to do this is to invoke Object#class and Module#name. For example:

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

Solution 3 - Ruby

I believe this would work fine too:

module Foo
  class Bar
  end
end

bar = Foo::Bar.new

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

This would result in

Bar

I also believe it would be a bit faster than the regular expression evaluation, but I'm not sure about this and I haven't performed a benchmark.

Solution 4 - Ruby

Suppose we have the following module Foo:

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

If you don't know what classes are contained in Foo, you might 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.

You can then do what you wish with the array a. Perhaps you want to narrow this to clases whose names end with "Bar":

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

If you want the portion of the names that excludes "Foo::" (though I can't imagine why), it's 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"] }

Note that there is no object Bar or Goo::Bar.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionironsandView Question on Stackoverflow
Solution 1 - RubyUelbView Answer on Stackoverflow
Solution 2 - RubyTodd A. JacobsView Answer on Stackoverflow
Solution 3 - RubyEd de AlmeidaView Answer on Stackoverflow
Solution 4 - RubyCary SwovelandView Answer on Stackoverflow