为什么ifTrue和ifFalse没有被分隔;在Smalltalk?

时间:2010-06-27 13:20:07

标签: smalltalk

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

我的理解是布尔a> b接收消息ifTrue:['greater'],然后ifFalse:['less or equal']符合泛化:

objectInstance selector; selector2

但是需要一个分号来指定selector2的接收者不是(objectInstance选择器)而是objectInstance。与上述条件执行不一样吗?

2 个答案:

答案 0 :(得分:19)

该方法的选择器为Boolean>>ifTrue:ifFalse:,这意味着它是一个方法,其中包含两个参数,而不是两个方法一个参数。

问题,要调用该方法,请使用两个块参数向其发送消息ifTrue:ifFalse:

请注意,为方便起见,还有方法Boolean>>ifFalse:ifTrue:Boolean>>ifTrue:Boolean>>ifFalse:

答案 1 :(得分:9)

所有相关的内容都已经说过了,但只是为了你的娱乐:

如前所述,

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

是单个和单个消息#' ifTrue:ifFalse:',其中2个args被发送到 rcvr 。该表达式的值是该消息发送的值。 相反:

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

是两个连续消息的级联(#' ifTrue:'和#' ifFalse:'),每个消息都有1个arg发送到 rcvr 。表达式的值是从上次发送返回的值。

现在有趣的是,布尔人确实理解 ifTrue: / ifFalse:(每个都有1个arg), 所以你的代码适用于副作用(评估这些块),但不适用于它的值。 这意味着:

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 中生成与:

不同的值
msg := a > b ifTrue:['gt'] ifFalse:['le']

取决于 a b 的值。尝试(a b)=(1 2)vs.(a b)=(2 1)...

许多Smalltalk初学者的问题是他们认为 ifXXX:是语法,它实际上是一个产生价值的消息发送。此外,半数不是许多以前学过的语言中的语句分隔符,而是序列消息发送构造。

初学者的一个坏陷阱,因为代码似乎适用于某些特定的值组合,而它会为其他人生成有趣的结果。 我们希望您的单元测试涵盖这些;-)

编辑:要查看错误值的来源,请查看布尔>>返回的内容。 ifFalse:真正接收者的方法......