解释一段Smalltalk代码?

解释一段Smalltalk代码?,smalltalk,Smalltalk,我无法理解这段Smalltalk代码: [(line := self upTo: Character cr) size = 0] whileTrue. 有人能帮你解释一下吗?如果你有代码来源的图像,一件简单的事情就是在上面运行一个调试器并逐步执行 如果您在上下文之外看到了这些代码,比如邮件列表帖子,那么您可以浏览其中一条消息的实现者并查看它的功能。例如,尺寸和尺寸都是非常标准的,所以我们现在将跳过它们,但直到:听起来很有趣。它让我想起了流方法,并在其上启动了实现者,这证实了(在Pharo 1.

我无法理解这段Smalltalk代码:

[(line := self upTo: Character cr) size = 0] whileTrue.

有人能帮你解释一下吗?

如果你有代码来源的图像,一件简单的事情就是在上面运行一个调试器并逐步执行

如果您在上下文之外看到了这些代码,比如邮件列表帖子,那么您可以浏览其中一条消息的实现者并查看它的功能。例如,尺寸和尺寸都是非常标准的,所以我们现在将跳过它们,但直到:听起来很有趣。它让我想起了流方法,并在其上启动了实现者,这证实了(在Pharo 1.1.1中),ReadStream定义了它。没有方法注释,但OmniBrowser在方法名称旁边显示一个小箭头,指示它是在超类中定义的。如果我们检查立即超类PositionableStream,就会有一个很好的方法注释来解释该方法的作用,它从流中提取,直到到达参数指定的对象

现在,如果我们从逻辑上分析代码,它似乎是:

  • 从流中读取一行(即,直到cr)
    • 如果为空(size=0),循环将继续
    • 如果不是,则返回
因此,代码跳过所有空行并返回第一个非空行。为了确认,我们可以在多行字符串上传递一个流,然后像这样运行它:

line := nil.
paragraph := '


this is a line of text.
this is another line
line number three' readStream.
[(line := paragraph upTo: Character cr) size = 0] whileTrue.
line. "Returns 'this is a line of text.'"

关于Smalltalk,我个人不太喜欢的一点是,尽管几乎所有事情都使用消息传递,但有时很难确定将什么消息发送给什么接收者。这是因为Smalltalk在消息发送周围没有任何分隔符(例如Objective-C),而是允许您在遵循一组优先级规则的同时链接消息发送,这些规则类似于消息发送从左到右进行解释,除非用括号分隔,否则首先计算具有多个关键字的消息,然后计算二进制关键字消息,然后计算一元关键字消息,然后计算没有关键字的消息。“当然,使用临时变量,甚至只使用括号来明确消息的顺序,可以减少需要考虑这种操作顺序的情况。下面是上述代码的一个示例,分为多行,使用临时变量和括号进行显式消息排序以提高可读性。我认为这更清楚地说明了代码的意图:

line = (self upTo: (Character cr)).

([((line size) = 0)] whileTrue).
所以基本上,line是在字符串self-up中连接字符直到回车字符(字符cr)时创建的字符串。 然后,我们检查行的字符大小,并检查它是否等于0,因为我们把它放在一个块(括号)中,我们可以发送一个whileTrue,它会重新计算块中的条件,直到它返回true。所以,是的,如果它被称为doWhileTrue或诸如此类的话,它的真实性会更清晰

希望能有所帮助。

这是否更具可读性:

while(!strlen(line=gets(self)))
如果出现feof或任何其他错误,则上述表达式存在缺陷,行==NULL
Smalltalk表达式也是如此,如果遇到流结束,upTo:将回答一个空集合,并且您将有一个无限循环,除非您有一个特殊的流在流结束时引发错误。。。试一试

String new readStream upTo: Character cr

Smalltalk的优先规则是
第一:一元消息
第二:二进制消息
第三:关键词消息
最后:从左到右

可以使用括号(即()括号)更改从左到右的顺序。首先计算括号对内的表达式。 在嵌套方括号的情况下,首先计算最里面的方括号,然后向外朝着外方括号,最后计算方括号外表达式的剩余部分

由于从左到右的倾向性很强,我经常发现从右到左阅读这个表达式是很有用的

所以对于
[(行:=self-upTo:Character-cr)size=0]而不是true.

从头到尾地理解它给了我们以下的解释

结束表达式。相当于

whileTrue
它的左边是什么<代码>]
块对象的闭合

因此
whileTrue
是发送到块的一元消息
[
..
]
i、 e.继续执行此块,而该块的计算结果为true

块返回在块中计算的最后一个表达式的结果

块中的最后一个表达式是
size=0
a比较。和一个二进制消息

size
通常是发送给接收者的一元消息。所以我们正在检查某物的
大小
,看看它是否为
0
。如果某物的
大小
0
,请继续

我们正在检查的
尺寸是多少?紧靠消息名称左侧的表达式。
size
左边是
(行:=self-up:Character cr)

这就是我们想知道的

所以,是时候把这个表达式放到刀下了

(行:=self-up:Character cr)
是一个赋值<代码>行
将产生
self-up:分配给它的字符cr

那个表达式的右端是什么
cr
它是一元消息,因此具有最高优先级。它被发送到什么地方。i、 e.
cr
消息的接收者是什么

紧靠其左侧的是
字符
。因此,向字符类发送消息
cr
这将计算为值为13的类字符实例-即回车字符

所以现在我们要讨论的是
self-up:aCarriageReturn

如果
self
-接收
self-upTo:aCarriageReturn
消息的对象不理解消息名称
sizeUpto:
它将