On Wed, Jun 16, 2010 at 3:23 PM, Josh C. [email protected]
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 = self 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 = x
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 = 1
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: rubyredrick (Rick DeNatale) · GitHub
Twitter: @RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale