Здравствуйте, kov_serg, Вы писали:
_>Прикольно наводит на мысли о подобных выражениях:
_>_>expression
_> ifTrue: ...
_> ifFalse: ...
_> ifLE: ...
_> ifNE: ...
_> ifGT: ...
_> ifOverflow: ...
_> ifException: ...
_>
Если заглянуть под капот (и даже на сам капот), то прикольность резко сходит на нет.
В смолтоке имя метода с несколькими аргументами разбивается на токены.
object say: "hello" to: "world"
эту же идею Бред Кокс позаимствовал, сделав смолток-поверх-си, и назвав его Objective C.
Естественно, методы say:to: и to:say: — это разные методы! Так же, как в си — say_to(greeting, address) и to_say(address, greeting).
Это такие именованные аргументы для бедных, — на самом деле, позиционные, но с улучшенной читаемостью.
Так вот, булевы выражения — это тоже методы
x and: y
x and: y and: z
x and: y and: z and: t
представьте себе, там реально три метода конъюнкции и три метода дизъюнкции, а если вам нужно пять и более операндов, тогда раскладывайте на скобки
((x and: y and: z and: t) and: u and: v and: w)
(не уверен, что такое сделано в squeak, но вот в pharo — было так).
Та же история с ветвлениями
x ifTrue: block1
x ifFalse: block2
x ifTrue: block1 ifFalse: block2
x ifFalse: block2 ifTrue: block1
Ради вот такой читаемости пришлось городить множество методов. Потому что сам язык не умеет в именованные аргументы, да и не очень-то хотелось.
Кстати, ещё одно откровение из-под капота.
Поскольку True и False — это синглетоны, унаследованные от базового класса Boolean, то они перегружают всё это разнообразие!
Там нет паттерна "шаблонный метод", есть копипаста.
True >> and: y
^ y.
True >> and: y and: z
^ y and: z.
True >> and: y and: z and: t
^ y and: z and: t.
False >> and: y
^ self.
False >> and: y and: z
^ self.
False >> and: y and: z and: t
^ self.
True >> ifTrue: then
^ then value.
True >> ifFalse: else
^ nil.
True >> ifTrue: then ifFalse: else
^ then value.
True >> ifFalse: else ifTrue: then
^ then value.
# аналогично - False
Смысл этого — в том, чтобы ускорить диспетчеризацию. Не надо проваливаться внутрь предка — Boolean, где могла быть (но не была) реализована вся логика.
Но вот что характерно, obj ifNil: / ifNotNil: более предпочтительно, чем (obj isNil) ifTrue: / ifFalse:
ровно потому, что у синглетона nil переопределены ветвления, и мы сэкономим время работы — вместо двух методов дёрнем один.
А для всех остальных типов — числа там, строки, коллекции... — сделаны только предикаты isSomething (ну и операторы сравнения), но не ветвления.
Иначе бы рантайм вообще яростно распух, наверное.