Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get class/module name

Tags:

Is there a better way to get class/module name viz, C from A::B::C, B from A::B::C, and A From A::B::C. The following code uses string and split to get "Stegosaurus" from Cowsay::Character::Stegosaurus, How to do away with string and split?

require 'cowsay'
x = Cowsay.random_character().class
x.name.split("::")[2]
require 'cowsay'
true
x = Cowsay.random_character().class
Cowsay::Character::Stegosaurus
x.name.split("::")[2]
"Stegosaurus"
like image 417
Impavid Avatar asked Oct 23 '16 21:10

Impavid


1 Answers

I don't think there's anything for handling this in core/standard library.

As an alternative to custom written methods there is always activesupport:

require 'active_support/core_ext/string/inflections'
Cowsay::Character::Stegosaurus.name.demodulize
#=> "Stegosaurus"
Cowsay::Character::Stegosaurus.name.deconstantize
#=> "Cowsay::Character"

These methods are implemented as follows:

def demodulize(path)
  path = path.to_s
  if i = path.rindex('::')
    path[(i+2)..-1]
  else
    path
  end
end

def deconstantize(path)
  path.to_s[0, path.rindex('::') || 0] # implementation based on the one in facets' Module#spacename
end

Take a look into docs if interested in more methods.

As to

A From A::B::C

If you'd require the whole activesupport, you'd get bunch of Module methods, including parent:

require 'active_support'
Cowsay::Character::Stegosaurus.parent
#=> Cowsay

If you're not going to use it extensively, I recommend to just grab the needed methods from activesupport and put it into some helper, because loading it whole might be an overkill.

like image 123
Andrey Deineko Avatar answered Sep 23 '22 16:09

Andrey Deineko