ReadWriteStream Issues

Richard A. O'Keefe ok at cs.otago.ac.nz
Tue May 6 05:23:21 UTC 2003


I wrote that
	>  It looks very much as if WriteStream>>on: aCollection
	>  should read
	>  self on: aCollection from: 1 to: aCollection size.

Anthony Adachi <adachipro at yahoo.com> asked:
	I'm no expert but how is that change going to affect
	existing methods which send messages to
	WriteStream>>on: aCollection? 	
	
(1) I don't know.  That's why my message was *not* a [FIX].
(2) Chances are that such methods should send #with: anyway.

	Before I show examples this is Squeak 3.5's
	definition, of the method you cite, for reference:
	[snipped, because it's exactly the same as 2.8]

	I did a quick scan of some senders of WriteStream>>on:
	
	AddParameterRefactoring >>> newSelectorString
	newSelectorString
		| stream keywords |
		stream := WriteStream on: String new.
		"... rest of expressions omited ..."
		
In this case, setting readLimit to (String new size) will have
precisely the same effect as setting it to 0.  There is no problem here.

		...Won't making that change will result in the write
	limit set to 0 for the stream temp variable
	(WriteStream instance)?

The change I suggested DOES NOT CHANGE THE INITIAL VALUE OF writeLimit.
The *only* difference in initial state is the initial value of readLimit,
which isn't all that relevant to WriteStreams anyway.

	Won't newSelectorString's code
	be upset when it tries to write to  stream?
		
No.  In this case the change doesn't affect the initial value at all.
WriteStreams expect to reallocate their underlying collection when it
fills up.

		As well, with...	
		
		AbstractSound pitchTable>>pitchTable
		"AbstractSound pitchTable"
	
		| out note i |
		out =: WriteStream on: (String new: 1000).
		"... rest of expressions omited ..."
		
		...won't that change will cause the read limit to be
	set to 1000? 

Yes, it will.  That is, indeed, the *POINT* of the change under
discussion.  But it doesn't matter in the least.  The point of the
readLimit instance variable is to tell #next whether it has reached
the end or not, and for WriteStream, #next is "self shouldNotImplement."
All the input methods inherited from Stream and PositionableStream
basically end up calling #next, so while WriteStream has a readLimit
instance variable, it does not actually allow reading.

WriteStream *does* allow you to call #atEnd.  The one observable
effect I can think of is that
    s := WriteStream on: 'abc' copy.
    s atEnd
currently returns true (position = readLimit = 0); with the
suggested change it would return false (position = 0 < readLimit = 3).
But since you can't call #next or (usefully) any other input method,
why would you care what #atEnd says?

	Didn't the authors wish to express
	something by using the message send of on: to
	WriteStream whose current implimentation sets the read
	limit to 0?
		
Yes, they wished to express "I want a WriteStream".
It is unlikely in the extreme that they gave a continental _what_
readLimit was set to, as long as everything worked.

	Or am I missing something hear? 
	
Yes.  What you are missing is that the Stream hierarchy is a couple
of decades overdue for refactoring.  It would actually make more sense
for ReadWriteStream to inherit from ReadStream; there are lots of methods
inherited by WriteStream but not actually useful to it, just so that
ReadWriteStream can inherit them.

If we suppose that someone thought it really mattered for a WriteStream
to always appear to be #atEnd, so that nobody _tried_ reading from it
even if they thought it was an input stream, then we have to explain
why whoever implemented #on:from:to: for WriteStream thought it
*didn't* matter.



More information about the Squeak-dev mailing list