Reputation: 654
I'm trying to do an arithmetic sequence class in smalltalk, I'm having some trouble with doing a printOn method. Here is the code I have, for some reason it would fail upon getting to the self part, I dont understand why though
printOn: aStream
|i retValue|
retValue := ''.
i := 0.
[i < myCount ] whileTrue: [retValue := retValue + ('', self valueOf: i). i := i -1.].
aStream nextPutAll: retValue
Upvotes: 3
Views: 356
Reputation: 13386
,
is a binary message. It has a higher priority than the valueOf:
keyword message. What you are actually executing looks like this:
('', self) valueOf: i
You need to put parenthesis to explicitly tell that you want valueOf:
executed first:
'', (self valueOf: i)
you do retValue + "probably string"
. Are you sure that you want to do +
in string and not ,
which is a concatenation?
you start from 0 and decrease i
by 1 on each step. Are you sure you will not end up in an infinite loop?
why do you need whileTrue:
? can't you do something like:
1 to: myCount do: [ :i |
retValue := retValue + ('', (self valueOf: i - 1)) ]
also please note that it's weird in Smalltalk that your first index is 0 and last is myCount - 1. Usually you start with 1 and end with the size of collection.
I've just noticed that you are actually concatenating an empty string with self valueOf: i
. That does not make any sense.
In case you just need to print things on the stream do something like:
printOn: aStream
1 to: myCount do: [ :i |
aStream nextPutAll: (self valueOf: i) asString) ]
or
printOn: aStream
(1 to: myCount)
do: [ :i | aStream nextPutAll: (self valueOf: i) asString) ]
separatedBy: [ aStream nextPutAll: ', ' ]
I don't know if valueOf:
returns a string, if it does, no need to send asString
to the result
Upvotes: 10
Reputation: 1136
Smalltalk has a rigorous precedence order for evaluating messages.
Expressions within parentheses ( ) are evaluated first.
Then Unary messages (messages consisting of an object followed by a message)
Then Binary messages (messages consisting of an object followed by non-alphabetic character followed by another object)
Then Keyword messages - i.e. keyword messages are evaluated last. (Keywords are alphabetic strings ending in a colon, and a keyword message can contain several keywords).
Where precedence is equal, expressions are evaluated from left to right.
In the expression you wrote, the first element evaluated in
retValue + ( '', self valueOf: i)
is
( '', self valueOf: i)
The first element evaluated within that expression is
'', self
The result of that then becomes the receiver of the
valueOf: 1
keyword message.
Incidentally, I would write
i := i - 1
To ensure that anySmalltalk would correctly interpret it as a binary expression, as opposed to i followed by an integer object, -1
Upvotes: 6