Y:= 3。 Z:= 4
。
h:='[x:= y + z。]'
(BlockClosure readFromString:h)值。
我有这个代码,我试图在smalltalk语法中使用一个字符串并尝试将其放入一个块并执行它但是我收到一个错误,其中说:
未处理的例外:消息未被理解#+
当我做了类似的事情
h:='[x:= 3 + 4。]'。
(BlockClosure readFromString:h)value
它运作得很好。我不明白为什么会这样。我猜y是没有指向任何东西,它不理解+方法。但为什么块不将y和z视为自由变量?
答案 0 :(得分: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.
我认为没有任何真正的方法可以使一个块的String表示在它被解析的上下文中像一个真正的闭包,因为它只是无法访问变量 - 并且无法编译。
答案 1 :(得分: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
但是,我建议您找到解决问题的更好方法。在运行方法的上下文中动态编译字符串非常棘手,可能很脆弱。
答案 2 :(得分:1)
James Robertson最近发布了他的blog regarding Dynamic Code Generation。 您可能会发现它很有用。