考虑以下消息序列:
1. s := '' writeStream.
2. s nextPutAll: '123'.
3. s skip: -3.
4. s position "=> 0".
5. s size "=> 3".
6. s isEmpty "=> false".
7. s contents isEmpty "=> true (!)"
不是6和7矛盾,或者至少是混乱吗?这种行为背后的逻辑是什么? (海豚有类似的功能。)
更新
正如@MartinW观察到的那样(请参阅下面的评论)ReadStream
和ReadWriteStream
表现不同(我们可以说,正如预期的那样。)
从实用的角度来看,我担心的兼容性更多的是FileStream
,其中contents
消息不仅限于当前position.
这样的差异使一个不错的“法律”无效任何与内存流(字符串或字节数组)一起使用的代码也适用于文件流,反之亦然。这种等价对于测试和教学原因非常有用。通过将方法#truncate
添加到WriteStream
可以轻松恢复明显的功能损失,这会明确地将size
缩短为当前position
[参见下面的讨论,德里克·威廉姆斯]
答案 0 :(得分:2)
在许多Smalltalks(如VAST)中,方法评论很好地解释了它:
WriteStream>>contents
"Answer a Collection which is a copy collection that the receiver is
streaming over, truncated to the current position reference."
PositionableStream>>isEmpty
"Answer a Boolean which is true if the receiver can access any
objects and false otherwise."
注意" 被截断为当前位置参考。"
在您的示例中,contents
是一个空字符串,因为您使用skip: -3
将位置设置为0。
这种行为不仅正确,而且十分有用。例如,考虑一种从集合构建逗号分隔列表的方法:
commaSeparatedListFor: aCollection
ws := '' writeStream.
aCollection do: [ :ea |
ws print: ea; nextPutAll: ', ' ].
ws isEmpty
ifFalse: [ ws position: ws position - 2 ].
^ws contents
在这种情况下,该方法可能已写入最终结尾",",但我们希望contents
将其排除。