Search code examples
smalltalkpharo

Smalltalk - Is it possible to add a string to a String instance via a method?


Smalltalk - Is it possible to add a string to a String instance via a method?

Essentially I'd like something along the lines of:

renderThisOn: aString

aString append: 'whatever text I want'

Essentially I'd like a String instance (ByteString, etc) to behave like the "html" object in Seaside. I pass it on as an argument to multiple methods, each adding some information to it.


Solution

  • From a practical viewpoint the answer would be no, it is not possible to change the size of a String. You can modify the characters of the String though:

    a := 'abc'.
    a at: 2 put: $x.
    a = 'axc' "true"
    

    Therefore, when you concatenate two strings you get a third one, while the others two remain unchanged

    s := 'abc'.
    t := 'def'.
    u := s , t.
    s = 'abc'. "true"
    t = 'def'. "true"
    

    Having said this, there is actually a way to do grow (or shrink) a String. The idea is to use become: (or becomeForward:). This message will replace all references to the receiver with references to the argument. In your case:

    s := 'abc'.
    t := 'def'.
    assoc := s -> 3 "referene to s"
    s become: s , t.
    s = 'abcdef'. "true"
    assoc key == s "true"
    

    The reason why I started my answer by saying that you cannot change the string's size is because in the vast majority of cases the use of become: is overkilling and the recommended practice is to review the code and eliminate the need for modifying the structure of an object.