03/10/2008

Clever ways to build strings

Mark Volkmann asked a question, on the beginners' list, about the best way to build a concatenated string. He wonder whether there was a benefit in doing one of the following:

Approach #1

s := ''.
s := s, 'foo'.
s := s, 'bar'

Approach #2

stream := WriteStream on: ''.
stream nextPutAll: 'foo'.
stream nextPutAll: 'bar'.
s := stream contents


Randal responded with this suggestion:


s := String streamContents: [:stream |
stream
nextPutAll: 'foo';
nextPutAll: 'bar'.
].

Then you don't even have to name the stream, because it has that
temporary name inside the block.


It has taken me a little while to understand how this works. Up to now, I have been thinking about blocks with arguments as having their argument passed in from the 'thing' they are associated with. E.g.

(1 to: 10) do: [:index| Transcript show: index]


In this case, the argument is created within the called method:

streamContents: blockWithArg
| stream |
stream := WriteStream on: (self new: 100).
blockWithArg value: stream.
^stream contents


This gives me a new way of thinking about arguments and blocks.

No comments: