一些WriteStream消息背后的逻辑是什么?

时间:2015-03-15 00:04:49

标签: smalltalk pharo

考虑以下消息序列:

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观察到的那样(请参阅下面的评论)ReadStreamReadWriteStream表现不同(我们可以说,正如预期的那样。)

从实用的角度来看,我担心的兼容性更多的是FileStream,其中contents消息不仅限于当前position.这样的差异使一个不错的“法律”无效任何与内存流(字符串或字节数组)一起使用的代码也适用于文件流,反之亦然。这种等价对于测试和教学原因非常有用。通过将方法#truncate添加到WriteStream可以轻松恢复明显的功能损失,这会明确地将size缩短为当前position [参见下面的讨论,德里克·威廉姆斯]

1 个答案:

答案 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将其排除。