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