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=== |
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=== |
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.) |
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 |
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 |
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 ======================================================================== === |
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. |
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 |
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 :) |
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 |
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 > > |
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 - |
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 |
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 - |
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 - > > |
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 - |
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. > |
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. > |
... 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. >> > > |
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 |
Free forum by Nabble | Edit this page |