Search code examples
smalltalk

Calling self inside a method in smalltalk


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

Solution

  • , 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)
    

    secondly:

    you do retValue + "probably string". Are you sure that you want to do + in string and not , which is a concatenation?

    thirdly:

    you start from 0 and decrease i by 1 on each step. Are you sure you will not end up in an infinite loop?

    fourthly

    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.

    fifthly

    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