Hello everyone.
I see a lot of code that follows the following pattern:
<a long expression> <aComplexTest>
ifTrue: [ <a long expression> <something> ]
ifFalse: [ <a long expression> <something else> ].
The classic refactoring is to store <a long expression> in a temp to avoid
repetition:
| temp |
temp := <a long expression>.
temp <aComplexTest>
ifTrue: [ temp <something> ]
ifFalse: [ temp <something else> ].
Then <a long expression> is evaluated once and the name of the temp can carry
a meaningful name that helps reading the code.
But this is more verbose than the first version.
But if you add the following method in Object:
if: conditionBlock then: trueBlock else: falseBlock
^ (conditionBlock cull: self)
ifTrue: [ trueBlock cull: value ]
ifFalse: [ falseBlock cull: value ]
You can then rewrite it like that:
<a long expression>
if: [ :obj | obj <aComplexTest> ]
then: [ :obj | <something> ]
else: [ :obj | <something else> ]
The names of the block args can give a meaningful name depending on the result
of the test (something like ... if: #notEmpty then: [ :collection | ... ] else:
[ :emptyCollection | ... ]). Using cull: for the three block also enable a
good flexibility: you can omit the arg when irrelevant.
Likewise, we could also have Object>>#while:do:
while: conditionBlock do: actionBlock
^ [ conditionBlock cull: self ] whileTrue: [ actionBlock cull: self ]
What do you think?
Camille