Search code examples
arrayssmalltalkgnu-smalltalk

How to have an instance variable that is an array


I would like to create a smalltalk application with a class that has an instance variable that is an array and an instance variable that is the array's size. I would ideally like to initialise these when the object gets created but I have these manually being initialised in a method.

The following is my code:

Object subclass: Student [
    | numTests marks |


    initialize [
        numTests := 0.
        marks := Array new: 10.
    ]
]
student := Student new.
student initialize.

But I get the following error:

Object: Array new: 10 "<0x10b054b80>" error: method is responsibility of a subclass

How can I solve this problem?


Solution

  • You may not really want to do this. I generally use Squeak derivatives and Array new: works but is often not what you want because Arrays are fixed size (i.e. you can't add or remove elements) and so you typically use something like OrderedCollection instead. Also, you generally don't want to store the size in an ivar but rather send #size to your collection whenever you need to know how many elements it contains.

    I've modified your code example based on the above suggestions (also notice that you don't need to send #initialize explicitly, it's done for you via #new:):

    Object subclass: Student [
        | marks |
    
    
        initialize [
            marks := OrderedCollection new: 10.
        ].
    
        addMark: newMark [
            marks add: newMark
        ].
    
        removeMarkAt: markIdx [
            marks removeAt: markIdx
        ].
    
        size [
            ^ marks size
        ]
    ]
    student := Student new.
    

    If you really need to create a fixed size array, please update the question with which Smalltalk variant you are using so that someone with specific knowledge of the implementation can help. The problem you appear to be running into is that your Smalltalk implementation considers Array an abstract class and therefore you need to instantiate a subclass of it to get a fixed size array.