How to get only class name without namespace

Solution 1:

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:

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

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

Solution 3:

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:

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.