在Ruby中“知道”类名的类方法?

时间:2010-11-13 06:20:52

标签: ruby inheritance metaprogramming

我希望继承的ruby类通过类方法“知道”它的类名。最好通过一个人为的例子说明这一点:

class Parent
  def self.whoami
    ??
  end
end

class Child < Parent
  #No code should be needed.
end

所以我应该可以致电:

Parent.whomai

并期望返回“父母”,然后我应该可以致电:

Child.whoami

期待“孩子”的回归我觉得在传统语言中这可能是不可能的。但Ruby的元编程模型以前让我感到惊讶。有什么想法吗?提前谢谢。

4 个答案:

答案 0 :(得分:20)

类方法是CLASS是接收器的方法,因此要查找调用该方法的对象(您在此处尝试执行的操作),只需检查self的值。 / p>

class Parent
  def self.whoami
    self
  end
end

class Child < Parent
end

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

答案 1 :(得分:15)

获取类名称(实际上是模块)的方法只是Module#name。没有必要自己编写:

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

然而,在Ruby中,确实没有像其他语言那样的“类名”。在Ruby中,类只是一个像任何其他对象一样的对象,它像任何其他变量一样被赋值给变量。

所有Module#name方法都循环遍历系统中的所有常量,并检查模块是否已分配给其中任何一个,并返回该常量的名称或nil如果找不到任何

所以,就像任何其他对象一样,类的“名称”真的除了用于引用它的变量之外什么都没有。

示例:

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

现在,班级的“名称”为foo。但是,Module#name会返回nil,因为foo不是常量。

bar = foo
bar.name # => nil

现在,该类的“名称” {/ em> foobar,但Module#name显然仍会返回nil

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

现在,由于该类已被赋值为常量,该常量的名称将被视为该类的名称...

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

...即使将常数分配给不同的东西......

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

...即使将课程分配到不同的常数后也是如此。

Module#to_s如果不是Module#name,则使用nil,因此,要打印课程名称,只需执行

puts Parent

在其他答案中,绝对不需要所有复杂的绒毛。

答案 2 :(得分:2)

这不是Parent.class告诉你的吗?

class Parent
  def self.whoami
    self.to_s
  end
end

class Child < Parent
end

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

答案 3 :(得分:1)

假设你上课:

class ABC
 def self.some_method
   self.name #it will return 'ABC'
   self.name.constantize #it will return ABC
 end
end