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



请考虑以下消息序列:

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中,可以轻松恢复明显的功能损失,这将明确缩短当前positionsize[参见下面与Derek Williams的讨论]

在许多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排除它。

相关内容

  • 没有找到相关文章

最新更新