Search code examples
smalltalkgnu-smalltalk

Extending default classes (SmallInteger)


I'm trying to extend the SmallInteger class with a new instance method "square". The idea is I wanna be able to call "5 square" and it'll return 25.

Extending your own classes with instance methods is fairly simple, since you know the variable names, but I don't know the variable names in the SmallInteger class. How can I find them?

I'm thinking it should look something like this, but 'thisNumber' is referencing whatever number this SmallInteger object happens to be.

SmallInteger extend [
    square [
        | r |
        r := thisNumber * thisNumber.
        ^r
    ]
]

Solution

  • I'm not a GNU-Smalltalk user but generally in Smalltalk the receiver of a method is represented by the pseudo-variable self. Therefore your method should look like

    square
      ^self * self
    

    Add the method to the instance side of the SmallInteger class and voilà.

    Note however that there already is a method that does that. Its selector is squared (with $d as its last character.) So, you don't really need to add square but the example might help you to understand Smalltalk a little bit more.

    Note in addition, that squared is not defined in SmallInteger but inherited from Number. The reason is that the message makes sense in all subclasses of that hierarchy and since in each of them the implementation would have been the same it is enough to have only one at the top (some dialects refine the method in Fraction for the sake of performance.)

    Of course, self * self could return a non-SmallInteger but a LargePositiveInteger. Fortunately, there is nothing special about that in Smalltalk so you can square any Number and it won't get truncated to any particular bit length.