Search code examples
smalltalkpharo

making a constructor in Pharo or Smalltalk


I want to implement a small class in Pharo so I have done this:

Object subclass: #Person
    instanceVariableNames: 'name age'
    classVariableNames: ''
    category: 'Test'

and I want to simulate a constructor so I have made a method like the following:

newName:aName newAge:aAge
    "comment stating purpose of message"

    name:=aName.
    age:=aAge.
    ^self.

but when I want to call it from the playground in Pharo like this:

objPerson:=Person newName:'Carl' newAge: 10.

it is not recognized by Pharo, what am I doing wrong?


Solution

  • The expression Person newName: 'Carl' newAge: 10 is a message to the class object Person. Therefore you have to implement it on the class side of Person.

    Your code needs to be tweaked like this

    Person class >> newName: aName newAge: anAge
      | person |
      person := self new.
      person name: aName.
      person age: anAge.
      ^person
    

    Note that in the code above self refers to the class because the method is on the class side. But since person is an instance of Person, the messages name: aName and age: anAge have to be defined on the instance side.

    Therefore, on the instance side, you need to add the two setters:

    Person >> name: aString
      name := aString
    
    Person >> age: anInteger
      age := anInteger
    

    With these three methods you should be able to run your example.


    Some additional comments on the coding style:

    Firstly, I would have chosen a different selector for the "constructor" method (in Smalltalk we call these "instance creation" methods). For instance,

    Person class >> named: aString age: anInteger
      ^self new name: aString; age: anInteger
    

    Secondly, there is no need to use the temporary person for the newly created instance as the expression self new already refers to such an instance.

    Finally, note the use of the cascade syntax in

    ^self new name: aString; age: anInteger
    

    which means that the message age: anInteger will be sent to the same receiver that name: aString, which in this case happens to be the new instance returned by self new.