I've written unit-tests for the current behavior. I do not agree with what we have currently, but this is not going to change so:
============== testStreamUseGivenCollection "self debug: #testStreamUseGivenCollection"
"When a stream is created on a collection, it tries to keep using that collection instead of copying. See thread with title 'Very strange bug on Streams and probably compiler' (Feb 14 2007) on the squeak-dev mailing list." |string stream|
string := String withAll: 'erased'. stream := WriteStream on: string. self assert: string = 'erased'.
stream nextPutAll: 'test'. self assert: string = 'tested'. "Begining of 'erased' has been replaced by 'test'". ==============
============== testNextPutAllDifferentFromNextPuts "self debug: #testNextPutAllDifferentFromNextPuts"
"When a stream is created on a collection, it tries to keep using that collection instead of copying. See thread with title 'Very strange bug on Streams and probably compiler' (Feb 14 2007) on the squeak-dev mailing list."
"nextPutAll verifies the size of the parameter and directly grows the underlying collection of the required size."
|string stream| string := String withAll: 'z'. stream := WriteStream on: string. stream nextPutAll: 'abc'. self assert: string = 'z'. "string hasn't been modified because #nextPutAll: detects that 'abc' is bigger than the underlying collection. Thus, it starts by creating a new collection and doesn't modify our variable." string := String withAll: 'z'. stream := WriteStream on: string. stream nextPut: $a; nextPut: $b; nextPut: $c. self assert: string = 'a'. "The first #nextPut: has no problem and replaces $z by $a in the string. Others will detect that string is too small." ==============