【发布时间】:2011-03-02 06:02:18
【问题描述】:
我正在使用 Pickaxe 1.9,但我对 instance/class_eval 块中的常量查找感到有些困惑。我正在使用 1.9.2。
似乎 Ruby 在 *_eval 块中处理常量查找的方式与它处理方法查找的方式相同:
- 在receiver.singleton_class(加上mixins)中寻找定义;
- 然后在receiver.singleton_class.superclass(加上mixins)中;
- 然后继续沿特征链向上直到到达
#<Class:BasicObject>; - 其超类是 Class;
- 然后沿着祖先链的其余部分(包括
Object,它存储您在顶层定义的所有常量),沿途检查混入
这是正确的吗? 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
【问题讨论】:
标签: ruby constants instance-eval