Почему ifTrue и ifFalse не разделены;в Smalltalk? - PullRequest
8 голосов
/ 27 июня 2010
a > b
ifTrue:[ 'greater' ]
ifFalse:[ 'less or equal' ]

Насколько я понимаю, Boolean a> b получает сообщение ifTrue: ['больше'], а затем ifFalse: ['меньше или равно'], соответствующее обобщению:

objectInstance selector; selector2

Но там нужно использовать точку с запятой, чтобы указать, что получатель selector2 - это не (селектор objectInstance), а objectInstance.Разве это не то же самое с вышеуказанным условным исполнением?

Ответы [ 2 ]

19 голосов
/ 27 июня 2010

Селектор метода - Boolean>>ifTrue:ifFalse:, что означает, что это метод one с двумя параметрами, а не two методами с one параметр.

Итак, чтобы вызвать метод, вы отправляете ему сообщение ifTrue:ifFalse: с двумя аргументами блока.

Обратите внимание, что по соображениям удобства существуют также методы Boolean>>ifFalse:ifTrue:,Boolean>>ifTrue: и Boolean>>ifFalse:.

9 голосов
/ 28 ноября 2012

Все релевантное уже было сказано, но только для вашего удовольствия:

Как уже говорилось,

rcvr ifTrue:[...] ifFalse:[...]

- это одно-единственное сообщение # ' ifTrue: ifFalse: 'с двумя аргументами, отправленными на rcvr .Значение этого выражения совпадает со значением этого сообщения send.Для сравнения:

rcvr ifTrue:[...]; ifFalse:[...]

- это каскад из 2 последовательных сообщений (# ' ifTrue: ' и # ' ifFalse: '), каждое из которых отправляет 1 аргументдо рчвр .Значением выражения является значение, возвращенное после последней отправки.

Теперь забавно то, что логические выражения действительно понимают ifTrue: / ifFalse: (каждый с 1arg), поэтому ваш код работает для побочного эффекта (оценивая эти блоки), но не для его значения.Это означает, что:

a > b ifTrue:[Transcript showCR:'gt'] ; ifFalse:[Transcript showCR:'le']

генерирует тот же вывод, что и:

a > b ifTrue:[Transcript showCR:'gt'] ifFalse:[Transcript showCR:'le']

, но:

msg := a > b ifTrue:['gt'] ; ifFalse:['le']

будет генерировать различные значения в msg than:

msg := a > b ifTrue:['gt'] ifFalse:['le']

в зависимости от значений a и b .Попробуйте (ab) = (1 2) против (ab) = (2 1) ...

Проблема многих начинающих пользователей Smalltalk заключается в том, что они думают о ifXXX: как о синтаксисе,где это на самом деле отправка сообщения, которое генерирует значение.Кроме того, semi - это не разделитель операторов, как во многих ранее изученных языках, а конструктив отправки сообщений секвенирования.

Плохая ловушка для начинающих, поскольку кажется, что код работает для некоторых конкретных комбинаций значений, тогда как он генерируетзабавные результаты для других.Будем надеяться, что ваши модульные тесты охватывают их ;-)

edit: чтобы увидеть, откуда исходит плохое значение, взгляните на то, что возвращает логический >> ifFalse: метод для истинного получателя ...

...