2013-10-25 36 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 

我建议你,但是,你找出解决问题的一个更好的方式。在正在运行的方法的上下文中动态编译字符串非常棘手并且可能很脆弱。

相关问题