Вы можете думать об отправителе как о self
.Другими словами, когда метод активирован (т. Е. Во время его выполнения), объект, представленный self
, может интерпретироваться как отправитель всех сообщений, отправляемых в теле метода.
Рассмотрим, например,метод #paint:
, определенный в OurClass
как
paint: aMorph
aMorph color: Color yellow
Как только этот метод будет выполнен, (суб) экземпляр OurClass
, получающий сообщение paint:
, станет self
.Ну, во время этой активации метода self
можно было бы отнести роль отправителя color:
к aMorph
.
Обратите внимание, что это всего лишь вопрос интерпретации.Например, вы также можете рассмотреть выполняемый процесс и определить отправителя как фрейм процесса, который активировал #color:
.
Хотя обе интерпретации верны, реальность такова, что в Smalltalk понятие отправителя не имеет значения, посколькупроцесс отправки сообщения является примитивным, т. е. реализуется в виртуальной машине, а не в виртуальном образе.
Конечно, для целей коммуникации полезно назначить эту роль кому-либо и даже говорить об отправителе.,Но предполагаемый объект зависит от контекста.Например, при отладке вы бы идентифицировали отправителя с вызывающим фреймом.Тем не менее, поскольку отправка сообщений происходит «волшебным образом», нет никакой необходимости прикреплять роль отправителя к какому-либо объекту.
Даже в Bee Smalltalk, где вы можете получить доступ к внутренним компонентам среды выполнения, потому что нет виртуальной машины, понятие отправителя также является суетливым и довольно ненужным.Технически говоря, каждая отправка в Bee имеет объект SendSite
, который выполняет все шаги, необходимые для отправки сообщения (PIC, поиск и т. Д.). И поскольку вы можете проверять эти объекты и отправлять им сообщения, вы можете предположить, что в Beeотправитель SendSite
.Но опять же, это подлежит интерпретации.На самом деле sender
ivar в классе SendSite
нет просто потому, что семантике Smalltalk в этом нет необходимости.
Addendum
Когда я говорю, что понятие sender
подлежит интерпретации, что я имею в виду, что такое понятие не используется ни в одной реализации механизма отправки.Точнее, (примитивный) код, который выполняет отправку, состоит из кэшированной подпрограммы, которая выполняет поиск метода, который учитывает только receiver
behavior
и selector
, не учитывая «отправителя».
Обратите внимание, что основной частью «данных», которые отправляет сообщение от «вызывающей стороны», являются аргументы.И если мы углубимся в реализацию всего этого машинного кода, мы можем утверждать, что другой - это адрес возврата, который используется для связи фреймов.Вот почему я упомянул понятие «отправитель» как относящееся к фрейму процесса вызывающего, что имеет смысл для его реализации в реализации отладчика.
Я хочу сказать, что в Smalltalk нет четкого определенияsender
, и поэтому его так трудно идентифицировать по сравнению с соответствующими понятиями, такими как receiver
, selector
, arguments
, behavior
и method send
.
Это правда, чтоВы можете использовать псевдопеременную thisContext
, чтобы получить sender
текущей активации.Если вы сделаете это, вы получите объект, который олицетворял self
в кадре вызова, что является другой интерпретацией sender
.И хотя, имея ссылку на этот объект, вы можете использовать его для предоставления дополнительных функций, sender
будет отсутствовать в объекте Message
и в механизме отправки сообщений.