在SmallTalk中,一切都是通过向Receiver对象发送消息来实现的。其语法通常遵循Receiver Message格式,其中Receiver是消息发送到的对象。现在我忍不住想知道,Small Talk消息的发送者是什么?考虑以下SmallTalk语句:
aMorph color: Color yellow我可以认为a Morph是消息的接收者,但发送者呢?标准的SmallTalk消息语法只有接收者和消息(选择器+参数),我无法识别发送者是什么以及在哪里。或者,消息实际上可以自动发送?
我记得在Pharo SmallTalk中浏览过一篇关于反射的文章,其中提到了消息的发送者,但我找不到也不明白这个‘发送者’是什么。谁能给我解释一下这件事?谢谢。
推荐答案无论何时发送消息,都会在运行时确定和设置发送方。从当前正在执行的方法的角度来看,它回答了"我们是如何做到这一点的"这个问题。在最常见的情况下,发送者将是发送导致当前方法被调用的消息的任何方法。例如,在Squeak中,如果doit在aMorph color: Color yellow上,发送者将是UnfinedObject>>doit,则发送者将是UnfinedObject>。如果您从MyObject>>myTestSender发送相同的邮件,则发件人将是MyObject>>myTestSender。
现在假设您将aMorph包装在一个proxy objectmyProxy中,它是MyProxyObject的一个实例,它的doesNotUnderstand:方法将它收到的所有内容转发给底层的aMorph对象。在本例中,当您执行myProxy color: Color yellow时,发送者将为MyProxyObject>>doesNotUnderstand:.(除非您的doesNotUnderstand:方法进一步操作运行库...这实际上是一个很好的示例,说明您可能需要查看#color:的发送者是谁:它被调用,但您不知道从哪里调用,因为代理添加了一个您可能不明显的间接级别。因此,为了查看发送者是谁,您可以向color:方法添加以下内容:
Transcript show: thisContext sender asString.从代码的角度来看,与发送者的处理是隐式的,在正常代码执行期间由SmallTalk运行时为您处理。除非您正在对一些代码进行故障排除,或者需要在运行时反思或更改某些内容,否则您不会经常看到发送者。
现在,这可能会引发这样一个问题:‘到底是什么?’它是一个表示调用堆栈顶部的特殊变量,许多人一开始都很难理解它。有关详细信息,请参阅How does Smalltalk manipulate call stack frames。附录(希望这将澄清Leandro的答案和我的答案之间的任何混淆)
Leandro的答案是将发送者视为一个通用术语,并考虑更大的历史背景,而我的答案是更现代的Squeak/Pharo中心术语,具有非常特定的含义。我同意Leandro的观点,即术语发送者是模棱两可的,并且不是跨实现标准化的(正如我们不同的答案所证明的那样)。为了进一步搅乱局势,Blue Book中提到的发件人是在谈论发送上下文...它既不是self也不是thisContext sender。然而,关于这一问题的评论中提到的链接在其含义上是明确的(即thisContext sender),正如在提到Squeak/Pharo代码时通常所指的那样。因此,哪一个答案是正确的取决于您是在查看特定的SmallTalk实现(在这种情况下,正确的用法是您正在使用的实现已经决定的任何一个),还是作为一个更一般的术语来讨论没有特定的SmallTalk实现(在这种情况下Leandro是正确的:它受到解释的影响,因为它的使用已经被重载到几乎没有意义)
更多推荐
SmallTalk:消息的发送者是什么?
发布评论