--0016364ef176fb7dee04892c6a65 Content-Type: text/plain; charset=ISO-8859-1 On Wed, Jun 16, 2010 at 2:56 PM, Rick DeNatale <rick.denatale / gmail.com>wrote: > On Wed, Jun 16, 2010 at 3:23 PM, Josh Cheek <josh.cheek / gmail.com> wrote: > > Besides I think that is not something you should do, because it means you > > are accessing ivars all over the place, which couples implementation. If > you > > always use the setter, then you have a gate keeper to that var, and can > > easily change implementation later, without having to go hunt down all > the > > places you used the ivars. > > This is a teapot which holds a tempest which has been brewing for 30 > years or more among users of languages like Ruby. > > Kent Beck covers this pretty well in his book Smalltalk Best Practice > Patterns, the two patterns "direct variable access" and "indirect > variable access" are two of the patterns in the book which are most > applicable to Ruby. > > direct variable access as the name implies is accessing an instance > variable directly by name > indirect variable access is ALWAYS using getter and setter methods to > access a variable. > > Kent describes the two as a tradeoff between simplicity and > readability (direct) vs. flexibility. > > Kent describes an experiment where he compared some Smalltalk code he > had written for a client who insisted on indirect variable access with > code he wrote for himself using direct variable access. He found that > he could read the dva code much more fluently, because he found that > everytime he ran across code like > > a elf x > > He paused just a bit to recognize that x was "just a getter" and not > some other kind of method. > > In Smalltalk methods always need an explicit receiver so that you need > to use "self x" instead of just x. > > Ruby's support for implicit receivers in this case allows for 'bare' > getter invocations, which actually exacerbates this because now > > a > > Might be a method call, but x might just be a local variable. You need > to widen the context when reading such code to determine which case it > is. > > And the reason that in Ruby you can't call a setter with just > > x > > is because even the Ruby parser can't tell that x is a method, so if > it hasn't seen it before in the local context as a method call it > assumes it's a local and defines it so if needed. > > On the other hand Ruby's use of the @ sigil to mark instance variable > names makes it completely clear that you are accessing an instance > variable if you use direct access. > > The main argument for indirect variable access is that it makes it > easier on subclasses because they can change how the 'attribute' is > implemented and inherited methods will use the overrided > implementation. > > This is true, and when you are building subclasses, it can be useful, > HOWEVER, in the course of programming in dynamically typed languages > over nearly 30 years in my case, I've matured to the point where I > realize that subclassing is a powerful tool, which, like many powerful > tools can be dangerous if not wielded with care. In fact that's one > of the main reasons I dislike statically typed "OO" languages, because > they force you to use inheritance to describe a type hierarchy, rather > than applying it with care when it makes sense for implementaion. > > Kent basically advises using direct variable access UNLESS indirect > variable access is more appropriate, and in either case to use one or > the other consistently for a given class and its subclasses. > > -- > Rick DeNatale > > Blog: http://talklikeaduck.denhaven2.com/ > Github: http://github.com/rubyredrick > Twitter: @RickDeNatale > WWR: http://www.workingwithrails.com/person/9021-rick-denatale > LinkedIn: http://www.linkedin.com/in/rickdenatale > > Thanks for the explanation, Rick. I've thought about it a bit, and I think for me, that using indirect access is the better choice in most situations (there are some situations where I use direct access, such as setting state for a view in Rails). I certainly take Kent's advice very seriously, though I'm curious whether his opinion is the same for Ruby as it is for Smalltalk. I also agree with you regarding subclassing, I'm having a hard time thinking of a situation where a subclass works that a module doesn't. --0016364ef176fb7dee04892c6a65--