开发者

Why ifTrue and ifFalse are not separated by ; in Smalltalk?

a > b
ifTrue:[ 'greater' ]
ifFalse:[ 'less or equal' ]

My understanding is that Boolean a > b receives the message ifTrue:[ 'greater' ], and then ifFalse:[ 'less or equal' ] complying to the generalization:

objectInstance selector; selector2

But there a semicolon is needed to specify that the receiver of selector2 is not (objectInstance selector) but ob开发者_JS百科jectInstance. Is not the same with the above conditional execution?


The selector of the method is Boolean>>ifTrue:ifFalse:, which means it is one method with two parameters, not two methods with one parameter.

Ergo, to invoke the method, you send it the message ifTrue:ifFalse: with two block arguments.

Note that for convenience reasons, there are also methods Boolean>>ifFalse:ifTrue:, Boolean>>ifTrue: and Boolean>>ifFalse:.


Everything relevant has already been sayd, but just for your amusement:

As already told,

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

is the one and single message #'ifTrue:ifFalse:' with 2 args sent to rcvr. The value of that expression is the one from that message send. In contrast:

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

is a cascade of 2 sequential messages (#'ifTrue:' and #'ifFalse:'), each with 1 arg sent to rcvr. The value of the expression is the one returned from the last send.

Now the funny thing is that booleans do understand ifTrue: / ifFalse: (each with 1 arg), so your code works for the side effect (evaluating those blocks), but not for its value. This means that:

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

generates the same output as:

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

but:

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

will generate different values in msg than:

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

depending on the values of a and b. Try (a b)=(1 2) vs. (a b)=(2 1)...

The problem of many Smalltalk beginners is that they think of ifXXX: as syntax, where it is actually a message send which generates value. Also, the semi is not a statement separator as in many previously learned languages, but a sequencing message send construct.

A bad trap for beginners, because the code seems to work for some particular value combinations, whereas it generates funny results for others. Let's hope your unit tests cover these ;-)

edit: to see where the bad value comes from, take a look at what is returned by the Boolean >> ifFalse: method for a true receiver...

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜