Class Method to 'Know' Class Name in Ruby?

11,583

Solution 1

A Class Method is a method where the CLASS is the receiver, so to find the object upon which the method is invoked (what you appear to be trying to do here) simply inspect the value of self.

class Parent
  def self.whoami
    self
  end
end

class Child < Parent
end

puts Parent.whoami #=> Parent
puts Child.whoami #=> Child

Solution 2

The method to get the name of a class (module, actually) is just Module#name. There's no need to write your own:

Parent.name # => 'Parent'
Child.name  # => 'Child'

However, in Ruby, there really is no such thing as a "class name" as there is in some other languages. In Ruby, a class is simply an object like any other object which gets assigned to a variable like any other variable.

All the Module#name method does is loop through all the constants in the system and check whether the module has been assigned to any one of them, and return that constant's name or nil if it cannot find any.

So, just like any other object, the "name" of a class is really nothing but whatever variable you use to refer to it.

Example:

foo = Class.new
foo.name # => nil

Now, the "name" of the class is foo. However, Module#name returns nil, because foo is not a constant.

bar = foo
bar.name # => nil

Now, the "name" of the class is both foo and bar, but Module#name obviously still returns nil.

BAZ = foo
foo.name # => 'BAZ'

Now, since the class has been assigned to a constant, that constant's name will be considered that class's name …

BAZ = nil
foo.name # => 'BAZ'

… even after the constant has been assigned to something different and …

QUX = foo
QUX.name # => 'BAZ'

… even after the class has been assigned to a different constant.

Module#to_s uses Module#name if it is not nil, so, to print the name of a class, you simply do

puts Parent

There's really absolutely no need for all the complex fluff in the other answers.

Solution 3

Isn't that what Parent.class will tell you?

class Parent
  def self.whoami
    self.to_s
  end
end

class Child < Parent
end

> Parent.whoami
=> "Parent"
> Child.whoami
=> "Child"

Solution 4

Suppose you class:

class ABC
 def self.some_method
   self.name #it will return 'ABC'
   self.name.constantize #it will return ABC
 end
end 
Share:
11,583
JP Richardson
Author by

JP Richardson

https://www.exodus.com - all-in-one app to secure, manage and exchange blockchain assets like Bitcoin and Ethereum.

Updated on June 14, 2022

Comments

  • JP Richardson
    JP Richardson about 2 years

    I want an inherited ruby class to 'know' its class name via a class method. This is best illustrated by a contrived example:

    class Parent
      def self.whoami
        ??
      end
    end
    
    class Child < Parent
      #No code should be needed.
    end
    

    So I should be able to call:

    Parent.whomai
    

    and expect a return of "Parent" I should then be able to call:

    Child.whoami
    

    and expect a return of "Child" I have a feeling that in conventional languages this might not be possible. But Ruby's metaprogramming model has amazed me before. Any thoughts? Thanks in advance.