Very strange bug on Streams and probably compiler

Ron Teitelbaum Ron at USMedRec.com
Wed Feb 14 15:54:25 UTC 2007


All,

This is a really good example of a string literal problem.  I'm a fanatic
about using copy after any hard coded string in code.  So much so that I've
had a number of developers make fun of my code because of it.  Whenever I'm
teaching someone Smalltalk I always include the "just use copy on all string
literals" suggestion.  But I normally show the problem with a character
replacement in a string instead.  This is a good example of how someone
might make a big mistake and then spend a lot of time trying to figure out
why everything is so messed up.

I was indoctrinated into the just-use-copy club by Versant.  If you had a
string literal in a method Versant stored your code in the DB.  Then if you
tried to change your code without being connected to the database everything
blew up! 

So this can be fixed by: 

|stream stream2|
	stream := WriteStream with: 'a test ' copy.
	stream reset.
	stream nextPutAll: 'to test' copy.
	self assert: [stream contents = 'to test' copy].

Ok the last copy is not really needed but "JUST USE COPY" works for me!

Ron Teitelbaum


> From: Bert Freudenberg
> Sent: Wednesday, February 14, 2007 10:36 AM
> 
> 
> On Feb 14, 2007, at 16:18 , Damien Cassou wrote:
> 
> > Execute the following piece of code:
> >
> >
> > "-------------------------------------------------------------------"
> > |stream stream2|
> > stream := WriteStream with: 'a test '.
> > stream reset.
> > stream nextPutAll: 'to test'.
> > self assert: [stream contents = 'to test'].
> >
> > "On the following line, you can remove 'copy'"
> > "the problem is present without. It's here to prevent"
> > " the streams from using the same collection"
> > "because the compiler tries to avoid creating 2 identical"
> > "strings"
> > stream2 := WriteStream with: 'a test ' copy.
> > stream2 nextPutAll: 'to test'.
> >
> > "This assert passes but this is abnormal"
> > self assert: [stream2 contents = 'to testto test'].
> >
> > "This assert pass and this is abnormal too"
> > "because the strings MUST be equal !!"
> > self assert: [stream2 contents ~= 'a test to test']
> > "-------------------------------------------------------------------"
> >
> >
> >
> > On my image, all the 3 tests pass. This is completely abnormal in
> > my opinion.
> 
> It is normal.
> 
> You are modifying the 'a test ' literal into 'to test'. This modified
> string gets copied in the second test.
> 
> Lesson: never modify string literals.
> 
> - Bert -
> 
> 
> 





More information about the Squeak-dev mailing list