2013-10-25 67 views
1

y:= 3。 Z:= 4。
h:='[x:= y + z。]'。
(BlockClosure readFromString:h)的值。將字符串分配給塊並以小寫形式執行它們

我有這樣的代碼,我正在嘗試採取在Smalltalk語法的字符串,並試圖把它放在一個塊並執行它,但我得到它說的錯誤:
未處理的異常:消息不被理解#+

當我做東西像
h:='[x:= 3 + 4。]'。
(BlockClosure readFromString:h)value

它工作得很好。我不明白爲什麼會發生這種情況。我猜y不是指向任何東西,它不理解+方法。但是,爲什麼塊不把y和z當作自由變量呢?

回答

4

你的問題是y和z在實際將字符串編譯爲塊的上下文中是未知的。你可能會是像這樣的東西更好:

h := '[ :y :z | x := y + z]'. 
(BlockClosure readFromString: h) value: 3 value: 4. 

雖然我懷疑的代碼可能不會工作,要麼 - 因爲x尚未宣佈任何地方,所以更正確的版本是:

h := '[ :y :z | y + z]'. 
x := (BlockClosure readFromString: h) value: 3 value: 4. 

我不認爲有任何真正的方法可以讓一個塊的字符串表示像一個真正的閉包一樣在它被解析的上下文中,因爲它只是無法訪問變量 - 而且會失敗編譯。

+0

這對我來說會是這樣的痛苦。但我認爲你的回答是有道理的。謝謝! –

3

如果你真的需要做到這一點,請嘗試以下操作:

| x y z h block | 
    y:=3. z:=4. 
    h:= '[x:= y+z.]'. 

    block := Compiler new 
     evaluate: h 
     in: thisContext 
     allowReceiver: true 
     receiver: self 
     environment: self class environment 
     notifying: nil 
     ifFail: [self error: 'Failed to compile']. 

    ^block value 

我建議你,但是,你找出解決問題的一個更好的方式。在正在運行的方法的上下文中動態編譯字符串非常棘手並且可能很脆弱。

相關問題