You can think of the sender as being self
. In other words, when a method is activated (i.e., during its execution), the object represented by self
can be interpreted as the sender of all the messages sent in the method's body.
Consider for instance the method #paint:
, defined in OurClass
as
paint: aMorph
aMorph color: Color yellow
As soon as this method is executed, the (sub)instance of OurClass
receiving the paint:
message, will become self
. Well, during this activation of the method, self
could be attributed the role of the sender of color:
to aMorph
.
Note however, that this is just a matter of interpretation. For instance, you could also consider the process being executed and identify the sender as the process frame that activated #color:
.
While both interpretations are valid, the reality is that in Smalltalk the notion of sender is irrelevant because the act of sending a message is primitive, i.e., implemented in the Virtual Machine, not in the Virtual Image.
Of course, for communication purposes it is useful to assign that role to someone and even speak about the sender. But the object implied depends on the context. For instance, when debugging, you would identify the sender with the calling frame. However, since message sends happen "magically", there is no actual need to attach the role of sender to any object.
Even in Bee Smalltalk, where you can reach the internals of the runtime because there is no VM, the notion of sender is also fussy and rather unnecessary. Technically speaking, every send in Bee has a SendSite
object that performs all the steps needed to send the message (PIC, lookup, etc.) And since you can inspect these objects and send messages to them, you could speculate that in Bee the sender is the SendSite
. But again, this is subject to interpretation. In fact there is no sender
ivar in the SendSite
class simply because the Smalltalk semantics doesn't need such a thing.
Addendum
When I say that the notion of sender
is subject to interpretation what I mean is that such a notion is not used in any implementation of the send mechanism. More precisely, the (primitive) code that performs the send consists of a cached routine that performs the method lookup, which only takes into account the receiver
's behavior
and the selector
, disregarding the "sender".
Note also that the main piece of "data" that the message send gets from the "caller" are the arguments. And if we dig deeper in the machine code realization of all of this, we could argue that the other one is the return address, which is used to link the frames. This is why I mentioned the notion of "sender" as referred to the caller process frame, which is meaningful for its reification in the implementation of the debugger.
My point is that in Smalltalk there is no clear definition of sender
and that's why it is so hard to identify it when compared to relevant notions such as receiver
, selector
, arguments
, behavior
and method send
.
It is true that you can use the pseudo variable thisContext
to get the sender
of the current activation. If you do this, you will get the object that impersonated self
in the calling frame, which is the other interpretation of sender
. And even though by having a reference to that object you could make use of it to provide more features, the sender
will remain absent from the Message
object and the message send machinery.
sender
. Do you remember seeing another word? Or are you asking how to retrieve the sender of a message? – Beerbohm