为什么 ifTrue 和 ifFalse 不用 ; 分隔在小话中?
a > b
ifTrue:[ 'greater' ]
ifFalse:[ 'less or equal' ]
我的理解是布尔 a > b 收到消息 ifTrue:[ 'greater' ],然后收到消息 ifFalse:[ 'less or equal' ] 符合泛化:
objectInstance selector; selector2
但是这里需要一个分号来表明selector2 的接收者不是(objectInstance 选择器)而是objectInstance。是不是和上面的条件执行一样?
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 objectInstance. Is not the same with the above conditional execution?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
该方法的选择器是
Boolean>>ifTrue:ifFalse:
,这意味着它是一个一个方法,带有两个参数,而不是两个带有一个参数的方法。因此,要调用该方法,您可以向其发送带有两个块参数的消息
ifTrue:ifFalse:
。请注意,为了方便起见,还有方法
Boolean>>ifFalse:ifTrue:
、Boolean>>ifTrue:
和Boolean>>ifFalse:< /代码>。
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:
andBoolean>>ifFalse:
.所有相关的内容都已经说过了,但仅供您娱乐:
如前所述,
只有一条消息 #'ifTrue:ifFalse:' 带有 2 个参数,发送到 rcvr 。该表达式的值是来自该消息发送的值。
相比之下:
是 2 个连续消息的级联(#'ifTrue:' 和 #'ifFalse:'),每条消息都有 1 个参数发送到rcvr。表达式的值是上次发送返回的值。
现在有趣的是,布尔值确实理解 ifTrue: / ifFalse: (每个都有 1 个参数),
因此您的代码适用于副作用(评估这些块),但不适用于其价值。
这意味着:
生成与: 相同的输出,
但是:
将在 msg 中生成与: 不同的值,具体
取决于 a 和 b 的值。尝试 (ab)=(1 2) 与 (ab)=(2 1)...
许多 Smalltalk 初学者的问题是他们将 ifXXX: 视为语法,实际上它是一个发送产生价值的消息。此外,semi 并不是像许多以前学过的语言那样的语句分隔符,而是一个排序消息发送结构。
对于初学者来说这是一个糟糕的陷阱,因为代码似乎适用于某些特定的值组合,而对于其他值组合却会产生有趣的结果。
希望您的单元测试能够涵盖这些;-)
编辑:要查看错误值的来源,请查看布尔值 >> 返回的内容。 ifFalse:真正接收者的方法...
Everything relevant has already been sayd, but just for your amusement:
As already told,
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:
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:
generates the same output as:
but:
will generate different values in msg than:
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...