message - 如何告诉对象执行消息

标签 message smalltalk squeak

我有一个对象和一个包含我想发送给它的消息的字符串。

例如,字符串“+ 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.

顺便说一句,上面(和下面)的代码是针对 Squeak 的,其他 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

“扩展”方法的实现留给好奇的读者;)

关于message - 如何告诉对象执行消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10461571/

相关文章:

user-interface - 为什么Squeak界面的外观和行为如此陈旧?

smalltalk - 如何在 Squeak smalltalk 的类中搜索字符串?包裹里面怎么样?

python - 像在 python 上一样打印 linux man-help

c++ - C++ 中的 PeekMessage 函数和命名管道

android - android Logcat 中的错误消息

smalltalk - 吱吱小声 : Why reduction of a fraction does not happen after numerator and denominator values are modified in the inspect window?

c++ - 错误 : no matching function for call to/candidates are

smalltalk - 在不创建 session 的情况下提供海边页面/组件

Smalltalk 延迟初始化作为方法调用?

smalltalk - 在Squeak/Pharo中浏览VisualWorks代码