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
.
#name:age:
selector instead of#setName:age:
. Other languages need to prependset
orget
to setters and getters because they have no other way of distinguishing between them. In Smalltalk the colon is part of the selector and then the use of these prefixes becomes superfluous. – Muire