Все релевантное уже было сказано, но только для вашего удовольствия:
Как уже говорилось,
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: метод для истинного получателя ...