Example: repr "return a representation of THIS object" |ic| ic := self class. ^(#('<!' (self class) ';' name, '!>') asString).
Unfortunately, not only is this clunky, it returns a string array rather than a character string. (Forgive any typos...I wanted a sensible example, but the reality was tested in the workspace.)
What I want is to just return a character string built from other character strings, some of which may be computer and other of which might be literal.
For example, what I might want returned could be the string '<!Android;Marvin!>'.
The only way I've been able to figure out how to do this is to create a sufficiently long string (after calculating the length of each piece) and then to use at:put:
Hi Charles,
Try something like this:
'<!', self class name, ';', name, '!>'
The comma character is actually is actually a message that is understood by strings. The message is implemented in class Collection (in the "copying" method category), and since strings are types of collections, it works for strings also.
Dave
On Sat, May 06, 2006 at 10:15:25PM -0700, Charles D Hixson wrote:
Example: repr "return a representation of THIS object" |ic| ic := self class. ^(#('<!' (self class) ';' name, '!>') asString).
Unfortunately, not only is this clunky, it returns a string array rather than a character string. (Forgive any typos...I wanted a sensible example, but the reality was tested in the workspace.)
What I want is to just return a character string built from other character strings, some of which may be computer and other of which might be literal.
For example, what I might want returned could be the string '<!Android;Marvin!>'.
The only way I've been able to figure out how to do this is to create a sufficiently long string (after calculating the length of each piece) and then to use at:put:
On 5/7/06, David T. Lewis lewis@mail.msen.com wrote:
The comma character is actually is actually a message that is understood by strings. The message is implemented in class Collection (in the "copying" method category), and since strings are types of collections, it works for strings also.
Hey, Newbies! In case you missed the implications of what Dave said, you can concatenate arrays, ordered collections, and bit arrays, as well. Once you learn how to concatenate strings, you can use that knowledge all over.
Also, some languages use + for concatenation, and I have always liked the fact that Smalltalk uses , because + ought to be commutitive.
If you are building very long strings by using , in an inner loop, it can be slow because you will have an N squared algorithm. You can convert that into a linear time algorithm by writing to an WriteStream using nextPut: and nextPutAll: and then asking the WriteStream for its contents. It leads to a little more complicated code, but on some programs in can create a dramatic performance improvement. In general, though, use "comma", since it is simpler.
-Ralph Johnson
If you are building very long strings by using , in an inner loop, it can be slow because you will have an N squared algorithm. You can convert that into a linear time algorithm by writing to an WriteStream using nextPut: and nextPutAll: and then asking the WriteStream for its contents. It leads to a little more complicated code, but on some programs in can create a dramatic performance improvement. In general, though, use "comma", since it is simpler.
You should avoid optimizing your code before making sure it needs an improvement. Nevertheless, here is a simple benchmark for the two techniques:
[| temp | temp := String new. (1 to: 100000) do: [:i | temp := temp, i asString]] timeToRun
Answers 75.202 milliseconds
[| temp | temp := WriteStream on: String new. (1 to: 100000) do: [:i | temp nextPutAll: i asString]] timeToRun
Answers 3.169 milliseconds
To get the string back from the Stream, use #contents:
myWriteStream contents
Bye
Am 09.05.2006 um 20:59 schrieb Damien Cassou:
If you are building very long strings by using , in an inner loop, it can be slow because you will have an N squared algorithm. You can convert that into a linear time algorithm by writing to an WriteStream using nextPut: and nextPutAll: and then asking the WriteStream for its contents. It leads to a little more complicated code, but on some programs in can create a dramatic performance improvement. In general, though, use "comma", since it is simpler.
You should avoid optimizing your code before making sure it needs an improvement. Nevertheless, here is a simple benchmark for the two techniques:
[| temp | temp := String new. (1 to: 100000) do: [:i | temp := temp, i asString]] timeToRun
Answers 75.202 milliseconds
[| temp | temp := WriteStream on: String new. (1 to: 100000) do: [:i | temp nextPutAll: i asString]] timeToRun
Answers 3.169 milliseconds
To get the string back from the Stream, use #contents:
myWriteStream contents
Since using a stream to construct a collection is a very common task, there is a nice helper construct for this:
String streamContents: [:stream | 1 to: 10000 do: [:i | stream print: i]]
This spares you to declare one temporary variable and is overall more readable.
Also, I used the stream's #print: method which will append a string representation of its argument - you could, of course, use #nextPutAll:, too.
Btw, do *not* put parens around "1 to: 10000". Of course this works, but writing "1 to: 10000 do:" uses the #to:do: message which is way more efficient, and a tiny bit shorter to read, too.
- Bert -
Since using a stream to construct a collection is a very common task, there is a nice helper construct for this:
String streamContents: [:stream | 1 to: 10000 do: [:i | stream print: i]]
This spares you to declare one temporary variable and is overall more readable.
Also, I used the stream's #print: method which will append a string representation of its argument - you could, of course, use #nextPutAll:, too.
Btw, do *not* put parens around "1 to: 10000". Of course this works, but writing "1 to: 10000 do:" uses the #to:do: message which is way more efficient, and a tiny bit shorter to read, too.
Thank you for all this advices. It will help.
beginners@lists.squeakfoundation.org