Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/visual-studio-2010/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 当父母';s class方法访问子类';s常数_Ruby_Oop - Fatal编程技术网

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