2015-09-06 29 views
2

例子:Smalltalk中的未聲明變量在哪裏?

st> [ fnord := 7 ] value 

我一直的印象是,他們走進SystemDictionary在Smalltalk下,但事實並非如此:

st> [ fnord := 7 ] value 
st> Smalltalk at: #fnord 
Object: SystemDictionary new: 512 "<0x2acfca382030>" error: Invalid argument #fnord: key not found 

然而,至少在GNU Smalltalk的,值似乎要堅持地方 ---訪問fnord收益權值:

st> [ fnord := 7 ] value 
st> fnord 
7 

更新:我想出瞭如何拆卸塊!這真的很難。

st> [ fnord := 7 ] block inspect 
An instance of CompiledBlock 
    header: 32768 
    clean-ness flags: 0 
    number of arguments: 0 
    number of temporaries: 0 
    number of literals: 4 
    needed stack slots: 8 
    method: UndefinedObject>>executeStatements 
    literals: [ 
    [1] {fnord} 
    [2] a BlockClosure 
    [3] #block 
    [4] #inspect 
    ] 
    byte codes: [ 
    [1] source code line number 1 
    [3] push 7 
    [5] store into Global Variable {fnord} 
    [7] pop stack top 
    push Global Variable {fnord} 
    [9] return stack top 
    ] 
[] in UndefinedObject>>executeStatements 

所以它肯定認爲它寫入到一個全局變量。

+1

我不明白Gnu Smalltalk(事實上,我無法真正想象從命令行執行Smalltalk),但是不應該使用臨時變量來獲得最小的可能範圍? SystemDictionary(即全局範圍)不會很好,因爲它會被大量的一次性條目污染。在其他類型的Smalltalk中,執行代碼不會「綁定」某個方法(例如,選擇文本並執行它)會得到一個臨時上下文(例如,您可能會在Pharo中看到UndefinedObject >> DoIt)。 –

+0

但是不要使用'|來聲明局部變量fnord |'?事實上,我設法反彙編這個塊,而且它絕對是試圖寫入一個全球---不管那是什麼...... –

+0

Hrm。我在Amber嘗試了這個,我的block沒有編譯,聲稱'fnord'沒有聲明。也許這是一個GSTism。不幸的是,我無法使用Squeak或Pharo,因此無法在此嘗試。 –

回答

2

未聲明的變量綁定進入名爲Undeclared的全局字典。該綁定(key->value對)一旦正確聲明,即被移至Smalltalk。例如,這是如何在加載代碼時解決前向引用問題。也就是說,當聲明它的代碼被加載之前使用變量時。

+0

這是標準的Smalltalk事物,還是特定於某個特定版本?我問,因爲我無法在我的(難以搜索的)藍皮書中找到「未聲明」。 –

+0

是的,它是標準的Smalltalk-80。 –