4
我有一个对象和一个包含我想发送给它的消息的字符串。如何告诉对象执行消息
例如,我想发送给某个整数对象的字符串'+ 5'。
如果是在工作区,然后我就只写“OBJ + 5”,但我需要它在运行时不知道提前字符串来完成...
我有一个对象和一个包含我想发送给它的消息的字符串。如何告诉对象执行消息
例如,我想发送给某个整数对象的字符串'+ 5'。
如果是在工作区,然后我就只写“OBJ + 5”,但我需要它在运行时不知道提前字符串来完成...
如果你可以单独参数从消息本身的信息,那么你可以在“执行”的消息发送:
obj := 3.
msg := '+'.
arg := 5.
result := obj perform: msg asSymbol with: arg.
否则,你将不得不使用的编译器,这将字符串转换成编译代码并执行:
obj := 3.
msg := 'self + 5'.
result := Compiler evaluate: msg for: obj logged: false.
的常用技术,以避免重复的编译是编译的块,其可以被更有效地评估:
obj := 3.
msg := '[:x | x + 5]'.
block := Compiler evaluate: msg.
result := block value: obj.
顺便说一句,上面的代码(及以下)为佳乐,其它Smalltalks可能有不同的方式来访问编译器。
还有一种更加恶意的方式,可以让你直接从字符串中访问变量。这是在“thisContext”执行编译后的代码(在这种情况下,你需要声明的临时瓦尔即使在工作空间):
| obj msg result |
obj := 3.
msg := 'obj + 5'.
result := Compiler new evaluate: msg in: thisContext to: nil.
不过,我不会推荐这最后的技术。执行通常比编译器更安全。也就是说,它可以用来实现一些严重的元程序。例如: -
| obj |
obj := 3.
'The result is {obj + 5}.' expand
的“扩大”的实现方法是留给好奇的读者;)
由于使用的编译器是什么我失踪了:) – Mugen