Двойная отправка в Фаро

Может ли кто-нибудь объяснить процесс двойной отправки в Pharo 4.0 с Smalltalk? Я новичок в Smalltalk, и мне трудно понять эту концепцию, поскольку она реализована в Java совершенно иначе, чем в Smalltalk. Будет очень полезно, если кто-нибудь сможет объяснить это на примере.

1 ответ

Решение

По сути, идея в том, что у вас есть метод:

  • #addInteger: который знает, как добавить целые числа,
  • #addFloat: который знает, как добавить поплавки,
  • и так далее…

Сейчас в Integer класс, который вы определяете + как:

+ otherObject

   otherObject addInteger: self

в Float Вы определяете это как:

+ otherObject

   otherObject addFloat: self

Таким образом, вам нужно только отправить + к объекту, а затем он попросит получателя добавить его с требуемым методом.

Другая стратегия заключается в использовании #adaptTo:andSend: методы. Например + в Point класс определяется как:

+ arg 

   arg isPoint ifTrue: [^ (x + arg x) @ (y + arg y)].
   ^ arg adaptToPoint: self andSend: #+

Который сначала проверяет, является ли аргумент Point, а если нет, просит аргумент адаптироваться к Point и отправлять какой-либо символ (операцию), это сохраняет некоторое дублирование методов, которые должны выполнить несколько иную операцию.

Collection реализует метод следующим образом:

adaptToPoint: rcvr andSend: selector

   ^ self collect: [:element | rcvr perform: selector with: element]

а также Number реализует это так:

adaptToPoint: rcvr andSend: selector

   ^ rcvr perform: selector with: self@self

Обратите внимание, что во избежание явной проверки типов мы могли бы определить этот метод в Point Сам так:

adaptToPoint: rcvr andSend: selector

   ^ (x perform: selector with: arg x) @ (y perform: selector with: arg y)

Вы можете увидеть больше примеров в этой презентации: http://www.slideshare.net/SmalltalkWorld/stoop-302double-dispatch

Другие вопросы по тегам