Please use accessors!

John Brant brant at cs.uiuc.edu
Sun Aug 1 18:19:10 UTC 1999


At 10:03 AM 7/31/99 -0700, Carl Gundel wrote:
>I understand the pragmatics of this issue well, but I feel compelled to make 
>a counterpoint about the above.  Code that accesses ivars directly can be 
>brittle.  In particular, code which uses both direct access and accessor 
>methods on the same ivars can behave in unpredictable ways.  Sometimes such 
>code survives for a very long time because it is brittle and hard to 
>understand, and no one wants to touch it for fear of breaking it.

Code that accesses ivars directly isn't any more brittle or harder to
understand than code that uses accessors. If this was so, I could transform
my brittle, hard to understand code that accesses ivars directly to
non-brittle, easy to understand code that uses accessors in a matter of
seconds. I don't claim to be able to do that, but I do claim that I can get
rid of direct variable referencing for a particular class in a few seconds.

Anyway, I prefer direct variable referencing. Here are my main reasons why:

*) With direct variable referencing, nobody can write "self instVar
anotherInstVar someOtherInstVar yetAnotherInstVar dependents first == self
ifTrue: [...]". You may claim that nobody would write such code, but I've
seen it too often. It usually comes from someone who has taken the one week
Smalltalk course in which they preach that you should always use accessors
but forget to teach that it shouldn't be used to navigate through objects.

*) Direct variable referencing is easier to refactor. It is easy to
determine every place that a variable is being referenced. Suppose you
wanted to remove your variable named "value". If you used direct variable
referencing then it is easy to see if anyone references it. However, with
accessors there will always be two references so you must determine if
those methods are being used. For a variable named "value" you'd most
likely have accessors named #value and #value:; determining if anyone sends
these messages to your object could be very difficult.


While I expect to have convinced nobody with my reasons, I  may have better
luck arguing for some improvements in the development environment:

Often I hear arguments that one should use accessors because it is easier
to debug since you can put debugging statements in the accessor methods. If
you where to use direct variable referencing, then you would have to change
a bunch of methods. On the other hand, people in the direct accessor camp
often claim that it is harder to debug a program with accessors since you
cannot tell by looking at the message send whether this just a simple
setter or is doing something more complex. Since probably 95% of all
accessors are simple, it is easy to step over something that looks like an
accessor only to find that half of your state has changed.

While both of these arguments are valid, I believe that they are really
problems with the development environment, not the programs. If the
development environment supported break/watchpoints, then one wouldn't have
to use accessors to easily add debugging statements. You would enter your
watchpoint and the development environment would add the necessary code to
all methods. 

To solve the accessor debugging problem, I believe that there should be
three buttons/menu options on the debugger. One for stepping over the
message, one for stepping into a complex method but stepping over
accessors, and finally one for stepping into every method. VisualAge treats
simple accessors as primitives so it always steps over them. However, there
are times when I want to step into the method so I can change the method,
but the debugger won't allow me to...


John Brant





More information about the Squeak-dev mailing list