Ruby 当父母';s class方法访问子类';s常数
给定以下代码:Ruby 当父母';s class方法访问子类';s常数,ruby,oop,Ruby,Oop,给定以下代码: class Parent CONSTANT = "Parent" def self.do_the_thing puts CONSTANT puts self::CONSTANT end end class Child < Parent CONSTANT = "Child" end 为什么不Child.do\u thing打印“Child”两次?在Child类上调用do\u thing方法时,self是Child,因此self::CONS
class Parent
CONSTANT = "Parent"
def self.do_the_thing
puts CONSTANT
puts self::CONSTANT
end
end
class Child < Parent
CONSTANT = "Child"
end
为什么不
Child.do\u thing
打印“Child”两次?在Child
类上调用do\u thing
方法时,self
是Child
,因此self::CONSTANT
是Child::CONSTANT
('Child')
当您在
父类上调用do\u thing
方法时,self
是Parent
,因此self::CONSTANT
是Parent::CONSTANT
(“Parent”)
但是,当您仅调用常量时,Ruby首先尝试在do\u thing
方法所在的位置查找该常量,这两种情况下都是父类。常量查找算法可以简化为:
词汇上的“外向”
继承“向上”
因此,它首先尝试在最近的词汇封闭模块/类定义中查找常量,然后是该模块定义的词汇封闭模块定义,依此类推。如果它在那里找不到常量,那么只有在之后它才会查看继承链
我不认为matz曾经为这个算法提供过正式的理由,但是这个算法类似于Newspeak中的方法解析算法,Gilad Bracha提供了以下理由:如果你写了一个方法,并且你在词汇封闭的上下文中有一个值就在你面前,这将是令人惊讶的,如果它从系统的一个完全不同的部分获取了一些其他值
转化为您的示例:常量
赋值实际上就在方法定义的正上方,如果该方法的作者没有在他眼前拾取被赋值的值,那么他会感到惊讶
在self::CONSTANT
案例中,通过使用:
范围解析操作符显式指定查找的起点,可以跳过词汇查找部分
注意:不幸的是,常量查找实际上并没有那么简单。遗憾的是,我不知道有什么好的描述。在她的著名文章中,yugui写道她没有时间了,并将在稍后的文章中解释不断查找,但不幸的是,她从来没有这样做
puts Parent.do_the_thing
# Parent
# Parent
puts Child.do_the_thing
# Parent
# Child