我正在通过Pickaxe 1.9工作,我对实例/ class_eval块中的常量查找感到困惑。我正在使用1.9.2。
Ruby似乎在处理* _eval块中的常量查找方式与方法查找相同:
#<Class:BasicObject>
; Object
,它存储您在顶层定义的所有常量),检查沿途的mixins 这是对的吗? Pickaxe的讨论有点简洁。
一些例子:
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'
在class_eval示例中,Foo-the-class不是沿着Foo-the-object的祖先链停止的!
以mixins为例:
module M
CONST = "M::CONST"
end
module N
CONST = "N::CONST"
end
class A
include M
extend N
end
A.instance_eval { CONST } # => "N::CONST", because N is mixed into A's eigenclass
A.class_eval { CONST } # => "N::CONST", ditto
A.new.instance_eval { CONST } # => "M::CONST", because A.new.class, A, mixes in M
答案 0 :(得分:1)
在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
基本上,常量是准词法范围的。这个USED在1.9.x和1.8.x分支之间是不同的,它使库交叉兼容性变得很痛苦,所以他们改回来了。
答案 1 :(得分:0)