[ANSI-Smalltalk] #contents on <collectionStream>
Richard O'Keefe
ok at cs.otago.ac.nz
Mon Oct 20 04:12:20 BST 2008
On 19 Oct 2008, at 11:59 pm, Paolo Bonzini wrote:
>> for WriteStream and ReadWriteStream answering
>> self upTo: position
>> but otherwise (i.e. for read-only streams) answering
>> self upTo: readLimit
>
> Shouldn't this be "position for ReadStream and ReadWriteStream, and
> readLimit for WriteStreams"? It seems to me that the two are
> substantially different cases and don't fit very well in the
> do-what-I-mean nature of #contents.
In Squeak, ReadWriteStream is a subclass of WriteStream,
but doesn't agree with it.
But there is no obvious reason why ReadWriteStream *should*
be a subclass of WriteStream.
The Blue Book says it is (page 204), but that's not the
standard, and I found it much easier to make
ReadWriteStream a subclass of ReadStream.
I can't for the life of me see why WriteStream should disagree
with ReadStream and WriteStream, and evidently the ANSI crew
didn't either.
Let me tell you why I don't think WriteStream should truncate
its contents.
I sometimes build a binary data structure something like this:
write some NULs at the beginning.
fill in the data, remembering certain
positions as I go.
go back to the beginning.
fill in the empty bits with forward links.
Let's make a toy example.
|s p|
s := WriteStream on: (ByteArray new: 1000).
s nextPut: 0.
s nextPut: 0.
pairs do: [:each |
s nextPutAll: each key asByteArray].
p := s position.
pairs do: [:each |
s nextPutAll: each value asByteArray].
s position: 0.
s nextPut: p // 256.
s nextPut: p \\ 256.
^s contents
Perfectly clear, straightforward code, using no stream
operations outside the standard, with a perfectly good
result required by the standard.
So why should I have to stick
s setToEnd.
before the last line if I don't want to lose all my data?
> For reading past and future values in WriteStream you could do "x
> setToEnd; contents" but I never found a usage for it.
There's one above.
> The current
> behavior is sometimes useful to do something like
>
> x do: [ :each | s print: each; nextPut: $, ].
> s skip: -1.
> ^s contents
>
> ... though these days #do:separatedBy: is much clearer and works with
> all streams.
Exactly so. I have learned to be extremely wary of "skip: -1".
More information about the ANSI-Smalltalk
mailing list