Class Method to 'Know' Class Name in Ruby?
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 befo开发者_运维技巧re. Any thoughts? Thanks in advance.
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
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.
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"
Suppose you class:
class ABC
def self.some_method
self.name #it will return 'ABC'
self.name.constantize #it will return ABC
end
end
精彩评论