此代码出现在两个rb_cvar_set
和rb_cvar_get
在MRI的variable.c
:
if (front && target != front) {
st_data_t did = id;
if (RTEST(ruby_verbose)) {
rb_warning("class variable %"PRIsVALUE" of %"PRIsVALUE" is overtaken by %"PRIsVALUE"",
QUOTE_ID(id), rb_class_name(original_module(front)),
rb_class_name(original_module(target)));
}
if (BUILTIN_TYPE(front) == T_CLASS) {
st_delete(RCLASS_IV_TBL(front),&did,0);
}
}
id
是变量名(@@foo
)的C-内部表示。
front
是其中变量当前访问类(B
/C
)。
target
是最远的祖先,其中变量具有也曾经被定义(A
)。
如果front
和target
是不一样的,红宝石警告class variable #{id} of #{front} is overtaken by #{target}
。
的变量名然后字面上删除从front
的RCLASS_IV_TBL,使得在随后的查找,该变量名搜索‘下落通过’或在‘冒泡’到最远的祖先变量被定义。
注意,此检查和删除发生不只是在CVaR的获得,但台以及:
$VERBOSE = true
module A; end
class B; include A; @@foo = 1; end # => 1
module A; @@foo = 3 end # => 3
class B; p @@foo = 1 end # => 1
#=> warning: class variable @@foo of B is overtaken by A
module A; p @@foo end # => 1
在这个例子中,即使它的A
的价值3
由价值1
被覆盖在B
被设置,我们仍然REC eive相同的警告它的B
的类变量被A
超越!虽然通常对于普通的Ruby编码器来说,发现其变量的值在各种可能意想不到的地方(即在“父”/“祖父母”/“叔叔”/“表兄弟”中)变化通常更令人惊讶。 /“姐姐”模块和类),触发器和措辞都表明警告实际上是意在告知该变量的“真理之源”改变了编码器。
@ArupRakshit这不是答案。其实,我的问题是出于这个答案。你的回答是这个问题的出发点。 – sawa
我得到了..让我想想.. :-)好问题。 –