开发者

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 
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜