I created a class named Die
(singular of Dice) and set an instance variable side
.
Object subclass: #Die
instanceVariableNames: 'side'
classVariableNames: ''
package: 'MyPackage'
I initialized the side
variable to 6 by default:
initialize
side := 6.
However I would like the ability to change the instance variable after the object has been created, like so:
myDie := Die new.
myDie side: 10. " it doesn't to work "
It seems to me that instance variables can only be changed by class methods. Is there a way to change it like above?
Also, I have a method roll
that returns a random number between 1 and the specified side. If I create two dice and want to roll two dice at the same time, or maybe three dice at the same time, should I create a different class, something like papercup
feed that with the number of dices and implement the roll method on the papercup instead?
Thank you.
You are on a right track. When you execute
myDie side: 10.
You send a message side:
to myDie
which is an instance of a class Die
. To "respond" to this message, the class die (or its superclasses) should implement a side:
method. Ideally, this method is going to look like this:
side: aNumber
side := aNumber
You see, pharo takes encapsulation very seriously, so instance variables can be directly accessed only by the object itself, and not by anyone from the outside. This is why you always have to create accessors, which is a good practice followed to a various extent by many programming languages.
Regarding your second question: it's a good idea to have a Papercup class, but if you don't need extensive features, the exact task can be achieved by the following code:
papercup := OrderedCollection new.
papercup
add: die1;
add: die2;
add: die3.
papercup collect: #roll
This way you will roll all the 3 dies and return a collection for 3 numbers (collect:
is the same as map()
in many programming languages). I provided a shorthand version, whereas the full way to write a collect is: papercup collect: [ :die | die roll]
when you specify a complete block (closure) and send the roll
message to each die.