Tim vs. Accessors

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
20 messages Options
Reply | Threaded
Open this post in threaded view
|

Tim vs. Accessors

Blake-5
Hey, all,

        If I may quote the esteemed Mr. Rowledge:

"Please, please, don't get in the habit of willy-nilly making accessors  
for every instance variable. All you're doing that way is opening the door  
to writing C code."

        I believe the issue here is encapsulation, which I think we can  
uncontroversially agree upon as a good thing.

        However, I've always tried to take encapsulation as far as I can,  
including using accessors as far as possible inside the object itself.  
I've saved myself a fair bit of work over the years by doing so. (After  
all, the benefits accrued by encapsulation to clients of an object are not  
excluded from the object itself.)

        To answer Tim's plea, I would point out that by default, I make said  
accessors private. But of course, Smalltalk doesn't have a private  
directive. Some would say, you can have private methods, you just have to  
designate them as such, and others respect them (or not) at their own  
peril.

        I would submit, then, that accessors are no more or less opening-the-door  
to C code than any other presumed private method.

        Thoughts?

        ===Blake===

Reply | Threaded
Open this post in threaded view
|

RE: Tim vs. Accessors

Ron Teitelbaum
Hi Blake,

I know I shouldn't respond to this, I've spent enough time arguing this in
person to know that both sides have very valid arguments and strong
opinions.  You know I just can't resist.

I create accessors and mutators for all instance variables.  I also create
fake senders for performed methods with comments that point developers to
where the methods are performed.  Why?  Because everything you can do to
help a developer understand what you did and why helps.  

Now I also try very hard to not use accessors and mutators outside the
context of the object.  It doesn't always work out that way.  I almost
always create instance creation methods.  I really do not support

MyClass new foo: bar; yourself

type creation from some other object.  I prefer

MyClass class >> createForFoo: aBar ...

I do this because it makes it much easier to trace a class and to figure out
how to use that class.

I know Tim said only create accessors and mutators for those ivars that
should be exposed external to the object, but I disagree.  The benefits to
clarity and traceability outweigh the potential abuse.  

Happy coding!!

Ron Teitelbaum
President / Principal Software Engineer
US Medical Record Specialists




> -----Original Message-----
> From: Blake
> Hey, all,
>
> If I may quote the esteemed Mr. Rowledge:
>
> "Please, please, don't get in the habit of willy-nilly making accessors
> for every instance variable. All you're doing that way is opening the door
> to writing C code."
>
> I believe the issue here is encapsulation, which I think we can
> uncontroversially agree upon as a good thing.
>
> However, I've always tried to take encapsulation as far as I can,
> including using accessors as far as possible inside the object itself.
> I've saved myself a fair bit of work over the years by doing so. (After
> all, the benefits accrued by encapsulation to clients of an object are not
> excluded from the object itself.)
>
> To answer Tim's plea, I would point out that by default, I make said
> accessors private. But of course, Smalltalk doesn't have a private
> directive. Some would say, you can have private methods, you just have to
> designate them as such, and others respect them (or not) at their own
> peril.
>
> I would submit, then, that accessors are no more or less opening-
> the-door
> to C code than any other presumed private method.
>
> Thoughts?
>
> ===Blake===



Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Blake-5
On Sat, 06 Oct 2007 19:57:47 -0700, Ron Teitelbaum <[hidden email]>  
wrote:

> I know I shouldn't respond to this, I've spent enough time arguing this  
> in person to know that both sides have very valid arguments and strong
> opinions.  You know I just can't resist.

I didn't know I was enabling an addiciton.<s>

> I create accessors and mutators for all instance variables.

OK.

> I also create fake senders for performed methods with comments that  
> point developers to
> where the methods are performed.  Why?  Because everything you can do to
> help a developer understand what you did and why helps.

Oh! That seems like a good idea, although perhaps illustrates a  
shortcoming in the tools somewhere?

I have a strong aversion to "perform" and similar things. I've seen them  
predominately in dBase languages where they--they're just horrifying.

> Now I also try very hard to not use accessors and mutators outside the
> context of the object.  It doesn't always work out that way.  I almost
> always create instance creation methods.  I really do not support
>
> MyClass new foo: bar; yourself
>
> type creation from some other object.  I prefer
>
> MyClass class >> createForFoo: aBar ...
>
> I do this because it makes it much easier to trace a class and to figure  
> out how to use that class.

Ah! I do, too, but you can't do that unless the class object has access to  
the instance object's variables--or you put in accessors. (Well, that's  
not exactly true, of course, you can build an instance method which serves  
an essentially similar purpose to an accesor or set of accessors. But in a  
lot of cases, that seems very forced.)

> I know Tim said only create accessors and mutators for those ivars that
> should be exposed external to the object, but I disagree.  The benefits  
> to clarity and traceability outweigh the potential abuse.

I understand his point, too. It just strikes me that ST requires a degree  
of responsibility. (Though it might not hurt to allow a designation as  
"private", "protected" or what-have-you, that could show up in a  
Shout/etc. editor.)

Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Ralph Johnson
In reply to this post by Blake-5
I agree with Tim on this one.  Don't make accessors for private variables.

It only takes a minute or two to refactor a class manually to make
accessors for a variable and to replace uses of the variable with use
of the accessors.  It takes only seconds with the refactoring browser.
 So, I do not buy the argument that accessors makes your code more
flexible.

Accessors make it hard to figure out who is really changing things.
This is especially true if your variables have typical names like
"name" or "contents" or "children".  If you look for all senders of
the accessors, you will get a huge list, most of whom are irrelevant.

So, code is much clearer if it does NOT use accessors for private
variables, and it is almost as easy to change as code that does.
Therefore, use accessors ONLY when you want a variable to be public.

-Ralph Johnson

Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

timrowledge
Ralph pretty much nailed my reasons for disliking the idea of always  
making accessors methods for instvars. I can't vouch for the  
refactoring browser though because I've never actually used it. Or  
even seen it so far as I can remember...

What really upsets me is seeing code like this:-

thisPerson officeLocation office location x: otherPerson  
officeLocation office location x + 12.

a) it looks awful
b) it is a direct transcription of the vile dot-notation from C (and  
other awful languages) that simply pillages structures on the  
assumption that you are refering to memory llocations
c) it assumes a static structure - any change in the structure of  
whatever the 'officeLocation' might return will probably break the code
d) it (obviously) completely ignores any idea of encapsulation

There's way too much code like this floating around. I'm sure I've  
even perpetrated some of it. Yuck.

tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Oxymorons: Software documentation



Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

johnmci
In reply to this post by Ralph Johnson

On Oct 7, 2007, at 2:43 AM, Ralph Johnson wrote:


> This is especially true if your variables have typical names like
> "name" or "contents" or "children".


Which reminds me if you use a local variable called 'name' in a class  
method say for example.


        name := 'safljalas'

name is *really* an instance variable on Class, as the point when you  
save the method I think there should be some warning about using  
class side instance variables found in the class hierarchy because  
this innocent mistake now has trashed your image.

This confuses the class/metaclass logic, later when I select my class  
Foo it shows as


Object subclass: 'safljalas'
        instanceVariableNames: ''
        classVariableNames: 'Instances'
        poolDictionaries: ''
        category: 'nil'


Browsing all usages of the class Foo then results in a walkback.

SystemDictionary(Object)>>error:
SystemDictionary(Dictionary)>>errorKeyNotFound
[] in SystemDictionary(Dictionary)>>associationAt: {[self  
errorKeyNotFound]}
SystemDictionary(Dictionary)>>associationAt:ifAbsent:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SystemDictionary(Dictionary)>>associationAt:
safljalas class(Behavior)>>allCallsOn
SystemNavigation>>browseAllCallsOnClass:

Also if you select 'Foo' and ask to browse the class it does bring up  
a browser but can't find the Foo class.

--
========================================================================
===
John M. McIntosh <[hidden email]>
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
========================================================================
===



Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

tblanchard
In reply to this post by Ralph Johnson

On Oct 7, 2007, at 2:43 AM, Ralph Johnson wrote:

> I agree with Tim on this one.  Don't make accessors for private  
> variables.
>

MMMMKay -  but I'm rather addicted to using them for lazy  
initialization.

Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Michael Rueger-4
In reply to this post by timrowledge
tim Rowledge wrote:
> Ralph pretty much nailed my reasons for disliking the idea of always
> making accessors methods for instvars. I can't vouch for the refactoring
> browser though because I've never actually used it. Or even seen it so
> far as I can remember...
>
> What really upsets me is seeing code like this:-
>
> thisPerson officeLocation office location x: otherPerson officeLocation
> office location x + 12.

http://en.wikipedia.org/wiki/Law_of_Demeter

But then people never stick to design rules/laws/best practices,
otherwise code like the above wouldn't be written in the first place.

Just stating "don't use accessors" will give people the idea that they
can use instVarAt: instead. Trust me, I've seen this...

And for me using accessors even for local inst vars is enforcing
ecapsulation, not the other way round.

Just MTC (Euro though ;-) )

Michael

Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Steven W Riggins

On Oct 8, 2007, at 2:27 AM, Michael Rueger wrote:

> And for me using accessors even for local inst vars is enforcing  
> ecapsulation, not the other way round.

This is where I agree with Michael.  Sure ok you can find people  
touching inst vars with a tool, but really, IF performance were no  
issue, only one place should touch the instance variable.

Now part of this might be from my world of never having tools to see  
which code is touching the inst var.  Putting a halt in a setter  can  
often be useless but putting code in that says "hey who is sending me  
this damn Frob when I only expect Wankers" check.

Even in small classes, I have been burnt by := code where I actually  
typoed in TWO places.  Tracking that down was a pain in the neck. :)

encapsulation via obfuscation just seems wrong to me.  There should be  
a better way to denote which methods are private and which are not,  
and have that enforced, or at the very least used as meta data for a  
code coverage/lint like tool.

Computers should work for us, not against us :)

Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

timrowledge

On 8-Oct-07, at 12:06 PM, Steven W Riggins wrote:

>
> On Oct 8, 2007, at 2:27 AM, Michael Rueger wrote:
>
>> And for me using accessors even for local inst vars is enforcing  
>> ecapsulation, not the other way round.
>
> This is where I agree with Michael.  Sure ok you can find people  
> touching inst vars with a tool, but really, IF performance were no  
> issue, only one place should touch the instance variable.

I don't so much disagree as don't understand how you can make that  
assertion.

As soon as you have a method that simply returns an instvar you have  
opened up access to anyone. Until and unless someone comes up with a  
good way of
a) specifying and
b) enforcing
privacy then that is simply the way it is. An instvar is hidden  
except for code written in the relevant class and subclasses - that's  
what I  would consider encapsulation. Smalltalk tools can trivially  
find you all the places where that instvar is referenced or written  
to; what other languages do is so irrelevant it's barely worth  
considering. They're not of any interest at all here.

A long time ago there was a proposal for 'Modular Smalltalk'  
originally developed by the Tektronix Smalltalk folks; as I recall  
they argued that it would be good exclusively to use messages to  
access instvars, to the point that defining such a method pretty much  
defined the existence of the instvar. I can't remember if there was  
any accompanying privacy model to contain the subsequently loosed  
disencapsulation genie. (Nasty chap; bad breath, loud shirts, odious  
opinions, nasty piggy eyes, flatulent, insistent)

If - and only if - we had a sensible message privacy model could I  
agree with such a system. What would be much more useful than arguing  
about trivia would be trying to define such a system and then maybe  
implement it. I shall now offer a few thoughts on what private  
messages should do..

Class to instance
I suggest that there needs to be a form of privacy that allows a  
class to send a message to an instance. This would be to protect  
instance initialisation methods. I suspect that it ought to be  
defined as allowing the instance to receive a message from any class  
in its inheritance tree rather than only from its actual class  
object. And yes I can already see some jerk writing the logical  
equivalent of instVarAt:put: in Object class so that they can abuse  
this form of privacy. Run fast, run far, little jerk, I'm coming for  
you on the back of the dragon on doom.

Instance to instance
I think most privacy is likely to be of the "this should only be sent  
by me to myself" type. There might be an argument for a form that  
allows for one instance of a class to send messages to another  
instance of the same class for the purpose of copying?

Privacy violation
What should happen? An exception? A resumable one? Core dump?

Implementation
I can't think of any way of doing this statically outside a few  
special cases where the selector is only used for a private method  
and so the compiler can trivially spot when it is out of limits.  
Since there is absolutely no reason that #fooble:bar: should not be  
private in one class and public in another, I doubt that would be a  
very useful case.
At runtime it seems we would need to check the flag of the method in  
some efficient manner (like a prim number perhaps) and then check for  
the sender to see if it meets the requirements.


tim
--
tim Rowledge; [hidden email]; http://www.rowledge.org/tim
Strange OpCodes: HALT: No-Op



Reply | Threaded
Open this post in threaded view
|

RE: Tim vs. Accessors

Ron Teitelbaum
Hi All,

I knew I shouldn't have said anything.  Tim has a very good point about
instVar references.  Squeak tools are very cool and I was very pleased to
find out how easy it was to find ivar references.  It's still something else
that has to be checked (read as could be missed).  

I still haven't changed my mind; good programming doesn't come from the lack
of accessors and mutators.  Neither does the presence of accessors and
mutators mean bad programming.  I'm not even sure I agree that having
accessors and mutators enables bad programming.  Their presence is not an
invitation to use them just as having a method is not an invitation to use
it either.  Sure you can chain yourself into a mess and do many many bad
things with accessors and mutators but you shouldn't do those things and
there is no replacement for talent and experience.

I think the best way to solve this argument once and for all is for us to
agree that accessors and mutators should be placed on all ivars, but that we
should also thoroughly document them in both the methods and the class
comments.  Oh and to all agree not to program badly!  How's that?

:)  

Ron Teitelbaum

> -----Original Message-----
> From: [hidden email] [mailto:squeak-dev-
> [hidden email]] On Behalf Of tim Rowledge
> Sent: Monday, October 08, 2007 4:19 PM
> To: The general-purpose Squeak developers list
> Subject: Re: Tim vs. Accessors
>
>
> On 8-Oct-07, at 12:06 PM, Steven W Riggins wrote:
>
> >
> > On Oct 8, 2007, at 2:27 AM, Michael Rueger wrote:
> >
> >> And for me using accessors even for local inst vars is enforcing
> >> ecapsulation, not the other way round.
> >
> > This is where I agree with Michael.  Sure ok you can find people
> > touching inst vars with a tool, but really, IF performance were no
> > issue, only one place should touch the instance variable.
>
> I don't so much disagree as don't understand how you can make that
> assertion.
>
> As soon as you have a method that simply returns an instvar you have
> opened up access to anyone. Until and unless someone comes up with a
> good way of
> a) specifying and
> b) enforcing
> privacy then that is simply the way it is. An instvar is hidden
> except for code written in the relevant class and subclasses - that's
> what I  would consider encapsulation. Smalltalk tools can trivially
> find you all the places where that instvar is referenced or written
> to; what other languages do is so irrelevant it's barely worth
> considering. They're not of any interest at all here.
>
> A long time ago there was a proposal for 'Modular Smalltalk'
> originally developed by the Tektronix Smalltalk folks; as I recall
> they argued that it would be good exclusively to use messages to
> access instvars, to the point that defining such a method pretty much
> defined the existence of the instvar. I can't remember if there was
> any accompanying privacy model to contain the subsequently loosed
> disencapsulation genie. (Nasty chap; bad breath, loud shirts, odious
> opinions, nasty piggy eyes, flatulent, insistent)
>
> If - and only if - we had a sensible message privacy model could I
> agree with such a system. What would be much more useful than arguing
> about trivia would be trying to define such a system and then maybe
> implement it. I shall now offer a few thoughts on what private
> messages should do..
>
> Class to instance
> I suggest that there needs to be a form of privacy that allows a
> class to send a message to an instance. This would be to protect
> instance initialisation methods. I suspect that it ought to be
> defined as allowing the instance to receive a message from any class
> in its inheritance tree rather than only from its actual class
> object. And yes I can already see some jerk writing the logical
> equivalent of instVarAt:put: in Object class so that they can abuse
> this form of privacy. Run fast, run far, little jerk, I'm coming for
> you on the back of the dragon on doom.
>
> Instance to instance
> I think most privacy is likely to be of the "this should only be sent
> by me to myself" type. There might be an argument for a form that
> allows for one instance of a class to send messages to another
> instance of the same class for the purpose of copying?
>
> Privacy violation
> What should happen? An exception? A resumable one? Core dump?
>
> Implementation
> I can't think of any way of doing this statically outside a few
> special cases where the selector is only used for a private method
> and so the compiler can trivially spot when it is out of limits.
> Since there is absolutely no reason that #fooble:bar: should not be
> private in one class and public in another, I doubt that would be a
> very useful case.
> At runtime it seems we would need to check the flag of the method in
> some efficient manner (like a prim number perhaps) and then check for
> the sender to see if it meets the requirements.
>
>
> tim
> --
> tim Rowledge; [hidden email]; http://www.rowledge.org/tim
> Strange OpCodes: HALT: No-Op
>
>



Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Bert Freudenberg
On Oct 9, 2007, at 3:39 , Ron Teitelbaum wrote:

> Their presence is not an
> invitation to use them just as having a method is not an invitation  
> to use
> it either.

For novices it is. Since we do not have any documentation of what  
methods comprise the "public interface" of a class, we always tell  
them to go look in the browser to find out.

> Sure you can chain yourself into a mess and do many many bad
> things with accessors and mutators but you shouldn't do those  
> things and
> there is no replacement for talent and experience.

True. However, I've seen what people do. Inexperienced programmers  
usually shy away from modifying other classes.
Not having accessors for each and everything in the first place makes  
them look for more appropriate methods.

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

David T. Lewis
In reply to this post by Ron Teitelbaum
On Mon, Oct 08, 2007 at 09:39:25PM -0400, Ron Teitelbaum wrote:
>
> I knew I shouldn't have said anything.  Tim has a very good point about
> instVar references.  Squeak tools are very cool and I was very pleased to
> find out how easy it was to find ivar references.

How does one find ivar references easily? I use "method strings with it" but
that would not qualify as easy.

Dave


Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Bert Freudenberg

On Oct 9, 2007, at 11:41 , David T. Lewis wrote:

> On Mon, Oct 08, 2007 at 09:39:25PM -0400, Ron Teitelbaum wrote:
>>
>> I knew I shouldn't have said anything.  Tim has a very good point  
>> about
>> instVar references.  Squeak tools are very cool and I was very  
>> pleased to
>> find out how easy it was to find ivar references.
>
> How does one find ivar references easily? I use "method strings  
> with it" but
> that would not qualify as easy.

It's in the class menu, or on a button when you enable the optional  
browser buttons. In the menu you can even look for assignments only.

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

David T. Lewis
On Tue, Oct 09, 2007 at 12:09:35PM +0200, Bert Freudenberg wrote:
>
> On Oct 9, 2007, at 11:41 , David T. Lewis wrote:
> >
> >How does one find ivar references easily? I use "method strings  
> >with it" but
> >that would not qualify as easy.
>
> It's in the class menu, or on a button when you enable the optional  
> browser buttons. In the menu you can even look for assignments only.

Ouch. Hard to imagine that it took me about a decade to discover this.
Thanks.

Dave

>
> - Bert -
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Bert Freudenberg

On Oct 9, 2007, at 12:27 , David T. Lewis wrote:

> On Tue, Oct 09, 2007 at 12:09:35PM +0200, Bert Freudenberg wrote:
>>
>> On Oct 9, 2007, at 11:41 , David T. Lewis wrote:
>>>
>>> How does one find ivar references easily? I use "method strings
>>> with it" but
>>> that would not qualify as easy.
>>
>> It's in the class menu, or on a button when you enable the optional
>> browser buttons. In the menu you can even look for assignments only.
>
> Ouch. Hard to imagine that it took me about a decade to discover this.
> Thanks.

Heh, I'm surprised. For me it's an essential tool for figuring out  
how stuff works. And it's even less hidden than tools like the  
protocol browser ...

- Bert -



Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

tblanchard
In reply to this post by David T. Lewis
More evidence that the menus could use a good refactoring...

On Oct 9, 2007, at 3:27 AM, David T. Lewis wrote:
> Ouch. Hard to imagine that it took me about a decade to discover this.
> Thanks.
>

Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Steven W Riggins
In reply to this post by David T. Lewis
I didn't know it until last week.

I guess these Sophie guys should have trained me or something :)


On Oct 9, 2007, at 3:27 AM, David T. Lewis wrote:

> Ouch. Hard to imagine that it took me about a decade to discover this.
> Thanks.
>


Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

Bert Freudenberg
... although in Tweak that looks for field references, too.

- Bert -

On Oct 9, 2007, at 19:28 , Steven W Riggins wrote:

> I didn't know it until last week.
>
> I guess these Sophie guys should have trained me or something :)
>
>
> On Oct 9, 2007, at 3:27 AM, David T. Lewis wrote:
>
>> Ouch. Hard to imagine that it took me about a decade to discover  
>> this.
>> Thanks.
>>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: Tim vs. Accessors

David T. Lewis
In reply to this post by Bert Freudenberg
On Tue, Oct 09, 2007 at 01:17:40PM +0200, Bert Freudenberg wrote:

>
> On Oct 9, 2007, at 12:27 , David T. Lewis wrote:
>
> >On Tue, Oct 09, 2007 at 12:09:35PM +0200, Bert Freudenberg wrote:
> >>
> >>On Oct 9, 2007, at 11:41 , David T. Lewis wrote:
> >>>
> >>>How does one find ivar references easily? I use "method strings
> >>>with it" but
> >>>that would not qualify as easy.
> >>
> >>It's in the class menu, or on a button when you enable the optional
> >>browser buttons. In the menu you can even look for assignments only.
> >
> >Ouch. Hard to imagine that it took me about a decade to discover this.
> >Thanks.
>
> Heh, I'm surprised. For me it's an essential tool for figuring out  
> how stuff works. And it's even less hidden than tools like the  
> protocol browser ...

Yep, I was staring right at it and I *still* didn't see it. I think
this must be like trying to find your own spelling errors. Once you
overlook something that's right in front of your eyes, your brain
tells you it's not there.

I learned Squeak by playing with it, and I suspect this is one of
the things that I did not understand early on, so I just started
overlooking it. Later when I wanted to find it, I did not "see" it
in the menus. So there is nothing wrong with the menus here, just
my dysfunctional brain ;)

Dave