JP *_*son 14 ruby inheritance metaprogramming
我希望继承的ruby类通过类方法"知道"它的类名.一个人为的例子可以很好地说明这一点:
class Parent
def self.whoami
??
end
end
class Child < Parent
#No code should be needed.
end
Run Code Online (Sandbox Code Playgroud)
所以我应该可以致电:
Parent.whomai
Run Code Online (Sandbox Code Playgroud)
并期望返回"父母",然后我应该可以致电:
Child.whoami
Run Code Online (Sandbox Code Playgroud)
并期望回归"孩子"我觉得在传统语言中这可能是不可能的.但Ruby的元编程模型以前让我感到惊讶.有什么想法吗?提前致谢.
hor*_*guy 21
类方法是CLASS是接收器的方法,因此要查找调用该方法的对象(您在此处尝试执行的操作)只需检查其值self.
class Parent
def self.whoami
self
end
end
class Child < Parent
end
puts Parent.whoami #=> Parent
puts Child.whoami #=> Child
Run Code Online (Sandbox Code Playgroud)
Jör*_*tag 15
获取类名称(实际上是模块)的方法就是Module#name.没有必要自己编写:
Parent.name # => 'Parent'
Child.name # => 'Child'
Run Code Online (Sandbox Code Playgroud)
但是,在Ruby中,实际上没有像其他语言那样的"类名".在Ruby中,类只是一个像任何其他对象一样的对象,它像任何其他变量一样被赋值给变量.
所有Module#name方法都是循环遍历系统中的所有常量,并检查模块是否已分配给它们中的任何一个,并返回该常量的名称或者nil它是否找不到任何名称.
所以,就像任何其他对象一样,类的"名称" 实际上只不过是用于引用它的任何变量.
例:
foo = Class.new
foo.name # => nil
Run Code Online (Sandbox Code Playgroud)
现在,班级的"名称"是foo.但是,Module#name返回nil,因为foo不是常数.
bar = foo
bar.name # => nil
Run Code Online (Sandbox Code Playgroud)
现在,这个类的"名"是既 foo和bar,但Module#name显然还是返回nil.
BAZ = foo
foo.name # => 'BAZ'
Run Code Online (Sandbox Code Playgroud)
现在,由于该类已被赋值为常量,该常量的名称将被视为该类的名称...
BAZ = nil
foo.name # => 'BAZ'
Run Code Online (Sandbox Code Playgroud)
...即使在将常数分配给不同的东西之后......
QUX = foo
QUX.name # => 'BAZ'
Run Code Online (Sandbox Code Playgroud)
......甚至在课程被分配到不同的常数之后.
Module#to_sModule#name如果不是nil,则使用,打印类的名称,你就是这样做的
puts Parent
Run Code Online (Sandbox Code Playgroud)
在其他答案中,绝对不需要所有复杂的绒毛.