December 21, 2024
Smalltalk Accessor Messages
Objects will require behaviour, and hence memory, if they are to simulate some aspect of the real world. To achieve this they are given attributes, or properties.
The authors of M206 decided upon a template, the Frog class, to manufacture a particular kind of object (instance), one that modelled real world frogs. These instances are given two attributes, position and colour, that are implemented using two instance variables position and colour. Instance variables are identifiers that reference other objects. These references are encapsulated inside every instance of the Frog class. The position instance variable references an object that is an instance of the SmallInteger class. When first created (initialised) a frog's position instance variable references 1. Its colour instance variable references another variable. This is a global variable, Green, so called because it is recognized anywhere within the Smalltalk system as a reference to a particular object, in this case an instance of the class ColorValue. Therefore we can say that this frog object holds some data, the value of its attributes, and that the values of this data are 1 and Green.
For a frog object to change its state, it must be sent messages that instruct it to "move 7 stones to the right" or "change colour to brown". We also need messages that request information, "what colour are you?", or "what's your position?". To achieve this we write methods containing code that will be executed when correspondingly named messages are sent to the frog receiver. These messages are called accessor messages. Frogs have colour , colour: , position and position: as accessor message selectors with corresponding methods colour , colour: , position and position:
N.B. the distinction between messages and message selectors is outlined on p3 of my Basic Smalltalk pdf document.
When we send the message colour to a Frog instance the following method is executed
colour
"Answer the colour of the receiver"
^colour
The colour method is about as simple as it gets. All it does is return a message answer that is an object, or to be more specific, a reference to an object. Frog objects will answer with something like Green or Brown.
The expression ^colour is a message answer expression and the ^ is called a caret. This instructs the Smalltalk system to answer the object that is returned by evaluation of the code that follows the ^. If you want to force a return in your code use a caret. Otherwise any Smalltalk method will, by default, return the receiver as the message answer.
Now consider the method corresponding to the message colour:
colour: aColour
"Set colour of receiver to aColour (for example,
Purple).Report change to user interface. Answer the
receiver."
colour := aColour.
self updateUserInterfaces
The colour: method looks a little more complex. You can forget the last
line of code for the moment. What it does is explained in the initial
comments "...Report change to user interface." You will look
at this much later in the course when looking at dependency mechanisms.
I will explain the term self very shortly, but for now let us consider
the line
colour := aColour.
Assignment is a mechanism that enables the Smalltalk system to reference an object with a variable. In this case, any instance of the Frog class has an internally stored instance variable colour which, depending on the current state of the Frog instance, references a particular global variable which in turn references an object that is an instance of ColorValue. There is a chain of references between the Frog object and the ColorValue object. To construct the chain we need to instruct the Smalltalk system that when a frog object receives the message colour: Green it sets the value of its instance variable colour to Green, another object. To achieve this we assign Green to the instance variable colour like so:
colour := aColour.
The period or full stop is needed because the method contains another line of code.
A word about the syntax used in the method heading. Because the message colour: requires an argument we write aColour (always start lower case and no spaces) in the method heading. However we could have written anything we liked e.g.
colour: aValue
"Set colour of receiver to aColour (for example,
Purple).Report change to user interface. Answer the
receiver."
colour := aValue.
self updateUserInterfaces
If the argument in the header is used as a reference in the method body, Smalltalk would compile this method without any problems. However, good programming practice is to give some clue as to the class of object needed for the argument. Consequently aColour makes better sense.
When an object receives a message it always returns a message answer, which is an object. In the colour: method there is no caret, therefore no forced message return. So what happens? As mentioned above, Smalltalk has a default message answer, which is the receiver of the message. For frog objects, if the method that is executed contains no forced message return, the message answer is the frog object that received the message, that triggered the method, which instructed the system to return the receiver.
In Learning Works, if you send the message position: 2 to a new frog instance
you will see in the message answer pane
An instance of class Frog (position 2, colour Green)
Is this the message answer? No, it is the textual representation of the frog object that received the message. The designers of LearningWorks could have written anything they liked such as:
A Frog object (position 2, colour Green)
As a student of M206, you need to remember the textual representation of Frog message answers and the same goes for the Account class. You also need to know that if aFrog (a variable that references a new instance of the class Frog) receives the message position: 2 then the message answer is aFrog. I will talk more about this in the next section.
Finally back to accessor messages. These messages usually, but not always, come in pairs, a getter and a setter (or get and set). This is pretty straight forward. The getter e.g. colour, gets the value of an instance variable and the setter e.g. colour:, sets the value of an instance variable.
The question that many students ask is this.
Should I, having implemented a getter and setter, reuse these messages
within other methods of the class? Or, can I simply use direct access
of the instance variable?
I touched upon this issue when discussing encapsulation. You might like
to take another look - here.
The next page will provide you with some guidelines on the use of accessor messages.
Next page » A guide to using accessors
Previous page « Methods
⇑ Up to top of page