此代碼出現在兩個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
我得到了..讓我想想.. :-)好問題。 –