Administrator
|
(WriteStream on: String new) nextPutAll: 'ab'.
is OK (WriteStream on: '') nextPutAll: 'ab'. gives an exception. Why? Thanks, Aik-Siong Koh |
Because '' is an immutable string literal, so can't be modified.
Randy On Jun 28, 2013, at 9:33 PM, askoh <[hidden email]> wrote: > (WriteStream on: String new) nextPutAll: 'ab'. > is OK > (WriteStream on: '') nextPutAll: 'ab'. > gives an exception. > > Why? > > Thanks, > Aik-Siong Koh > > > > -- > View this message in context: http://forum.world.st/VW7-9-WriteStream-wierdness-tp4696240.html > Sent from the VisualWorks mailing list archive at Nabble.com. > _______________________________________________ > vwnc mailing list > [hidden email] > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
And why was '' made immutable? Because it is part of a CompiledMethod. In this case it was just a temporary CompiledMethod, run from a workspace, but the more common case is when it is in a method in a class, e.g. something like:
returnString: aStringOrNil
"return the result of writing the string argument after writing it to a stream. If it is nil, return the string we use to initialize the stream"
| initialString stream | initialString := ''. ^aStringOrNil isNil ifTrue: [initialString] ifFalse: [stream := WriteStream on: initialString. stream nextPutAll: aStringOrNil. stream contents] That is compiled to a CompiledMethod in the class, with bytecode for the operations, and the literals including ''. Let's assume there is no immutability. When this method is run the first time with argument 'ab', the stream has as its collection '' and tries to write 'ab' into it, sees its collection is too small, grows it (i.e. creates a new, longer string '???', where ? is Character value: 0, and does #become: to swap it with the original ''), then writes 'ab' onto it: 'ab?'. #contents returns the result copyFrom: 1 to: 2, 'ab'.
However, the CompiledMethod is left pointing to the longer string, 'ab?' - remember that #become: makes all existing references to the original object ('') point to the new object. The source code is unchanged, but running methods doesn't look at the source code, just the compiled code. So, if we then run the method again with nil as an argument, instead of the expected '' it returns 'ab?'.
VW 7 (?) solved this by introducing immutability and making immutable all collection literals used by a method. This removed a source of surprising bugs, whose behaviour appeared crazy because it didn't match the source code.
All the best,
Steve From: [hidden email] on behalf of Randy Coulman Sent: Sat 29/06/2013 07:41 To: askoh Cc: [hidden email] Subject: Re: [vwnc] VW7.9 WriteStream wierdness Because '' is an immutable string literal, so can't be modified. _______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
Free forum by Nabble | Edit this page |