Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.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:在instance\u eval/class\u eval中常量查找是如何工作的?_Ruby_Constants_Instance Eval - Fatal编程技术网

Ruby:在instance\u eval/class\u eval中常量查找是如何工作的?

Ruby:在instance\u eval/class\u eval中常量查找是如何工作的?,ruby,constants,instance-eval,Ruby,Constants,Instance Eval,我正在学习Pickaxe1.9,对于实例/类评估块中的常量查找,我有点困惑。我用的是1.9.2 Ruby处理*_eval块中常量查找的方式似乎与处理方法查找的方式相同: 在receiver.singleton_类(加上mixin)中查找定义 然后在receiver.singleton_class.superclass中(加上mixin) 然后继续沿着特征链向上走,直到到达# 谁的超类是Class 然后在祖先链的其余部分(包括对象,它存储了您在顶层定义的所有常量)上检查混合 这是正确的吗?鹤嘴锄的

我正在学习Pickaxe1.9,对于实例/类评估块中的常量查找,我有点困惑。我用的是1.9.2

Ruby处理*_eval块中常量查找的方式似乎与处理方法查找的方式相同:

  • 在receiver.singleton_类(加上mixin)中查找定义
  • 然后在receiver.singleton_class.superclass中(加上mixin)
  • 然后继续沿着特征链向上走,直到到达
    #
  • 谁的超类是Class
  • 然后在祖先链的其余部分(包括
    对象
    ,它存储了您在顶层定义的所有常量)上检查混合
  • 这是正确的吗?鹤嘴锄的讨论有点简明扼要

    一些例子:

    class Foo
      CONST = 'Foo::CONST'
      class << self
        CONST = 'EigenFoo::CONST'
      end
    end
    
    Foo.instance_eval { CONST } # => 'EigenFoo::CONST'
    Foo.class_eval { CONST } # => 'EigenFoo::CONST', not 'Foo::CONST'!
    Foo.new.instance_eval { CONST } # => 'Foo::CONST'
    

    在1.9.2中,常量查找再次更改为与1.8.7行为等效

    class A
      class B
        class C
        end
      end
    end
    
    A.class_eval { B } # => NameError
    A.instance_eval { B } # => NameError
    A.new.instance_eval { B } # => A::B
    
    基本上,这些常量是准词汇范围的。这在1.9.x和1.8.x分支之间曾经是不同的,它使库的交叉兼容性成为一个难题,所以他们将其改回来


    常量有效地限定了词汇范围,因此您不能在定义它们的模块层次结构之外直接访问它们。这里有一个很好的解释,有点离题,但读起来不错。

    注意:对于Ruby 2.3来说,这不再是事实。
    class A
      class B
        class C
        end
      end
    end
    
    A.class_eval { B } # => NameError
    A.instance_eval { B } # => NameError
    A.new.instance_eval { B } # => A::B