Ruby:在instance\u eval/class\u eval中常量查找是如何工作的?
我正在学习Pickaxe1.9,对于实例/类评估块中的常量查找,我有点困惑。我用的是1.9.2 Ruby处理*_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 然后在祖先链的其余部分(包括对象,它存储了您在顶层定义的所有常量)上检查混合 这是正确的吗?鹤嘴锄的
#
李>
对象
,它存储了您在顶层定义的所有常量)上检查混合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