@var = change to accessor method? Why?

In ZenTest 3.9.0’s release notes
(http://blog.zenspider.com/archives/2008/01/zentest_version_390_has_been_released.html),
it says, “Cleaned out nearly every @ and use accessor methods instead.
You should too.”

My first thought was, “What?” So in a blog comment, I asked about it.
Here’s that (brief) exchange:
http://blog.zenspider.com/archives/2008/01/zentest_version_390_has_been_released.html#comments.
I may still get an answer there, but it occurred to me that wider
discussion might be better anyway (and he’s probably on this list,
yes?). I understand, now, that there is a difference and what that
difference is (I think), but I still don’t see why the latter is
better.

So… what’s the advantage of changing

class Thing
attr_accessor :a

def do_something(arg)
@a = arg
end
end

to…

class Thing
attr_accessor :a

def do_something(arg)
self.a = arg
end
end

Am I missing some context that’s helpful in understanding this? I’d
think that it would be more valuable for readability to keep the @var
assignment since it clues you in to the nature of the variable (vs. a
class variable, etc.) than… anything else I can come up with. I will
be the first to admit that, “anything I can come up with,” is a
pitifully small set of ideas. I’m not trying to say that this idea is
bad or whatever… I’m wondering what I don’t know. Thanks in advance
for illumination.

Ben

Day wrote:

to…

class Thing
attr_accessor :a

def do_something(arg)
self.a = arg
end
end

If you ever decide that the setter method should do more than just
change the
var (like for example validate the input and then change the var), you
can
replace the method created by attr_accessor with your own. Places where
you
directly assign to @a won’t benefit from that change, though.

HTH,
Sebastian

On Feb 1, 2008, at 10:54 AM, Day wrote:

class Thing
attr_accessor :a

def do_something(arg)
self.a = arg
end
end

imagine that you now want to know everywhere @a is set, perhaps
because you have a bug. you can start greping or simply

def a= value

 p caller
 @a = 42

end

done.

also, i don’t use ‘self.a’, but via attributes or fatter

class C
size 42
end

where ‘size’ is a getter defined thusly

def a *value
if value.empty?
@a
else
send ‘a=’, value.first
end
end

which eliminates the oh so tiresome self.

another huge advantage if using uniform access is that you can do
things like

class C
attributes 'a, ‘b’, ‘c’
end

p C.new.attributes => [‘a’, ‘b’ , ‘c’]

which is to say you can keep track of what state and object is likely
to contain. making things like serialization trivial to write.

regards.

a @ http://codeforpeople.com/

i’m on your side, ben. i don’t think that using accessor methods for
every instance variable is advisable.

basicly it’s a 2nd encapsulation of an attribute within an object that
undermines the encapsulation that comes with oo design.

i think in a good oo design one should think twice for every instance
variable that gets an accessor. and it’s the privilege of an object’s
methods to be able to write to instance variables directly.

if one feels the urge to encapsulate an instance variable within an
object, maybe it’s time to write another class.

g phil

On Feb 1, 2008, at 10:05 , ara howard wrote:

which eliminates the oh so tiresome self.

I personally don’t mind the “self”… I only really use it to be
explicit and sometimes the inconsistency of needing the self on
assignment vs not on read is slightly annoying.

I don’t mind the self because I love seeing my little message sends
all over. makes me warm and fuzzy all over. :stuck_out_tongue:

On Feb 3, 2008, at 18:18 , Philipp H. wrote:

basicly it’s a 2nd encapsulation of an attribute within an object that
undermines the encapsulation that comes with oo design.

How exactly does making/using an accessor method “undermine the
encapsulation”?

Philipp H. wrote:

accessors are meant to make the instance variables of an object to be
accessible from outside. creating accessors for every variable used in
an object (in order to get rid of @s) makes every variable accessible
from outside the object. therefore the data is not encapsulated any
more.

The data is still encapsulated, although the standard attr_accessor and
attr_writer lets everything just pass through. But writing an accessor
that for example prevents data to be set to certain values isn’t exactly
a hard task.

But since Ruby has a method to access the instance variables directly
anyway, the encapsulation is “undermined” even without accessors.

Best regards,

Jari W.

On Mon, Feb 04, 2008 at 06:57:21PM +0900, Ryan D. wrote:

On Feb 3, 2008, at 18:18 , Philipp H. wrote:

basicly it’s a 2nd encapsulation of an attribute within an object that
undermines the encapsulation that comes with oo design.

How exactly does making/using an accessor method “undermine the
encapsulation”?

what i meant is:

accessors are meant to make the instance variables of an object to be
accessible from outside. creating accessors for every variable used in
an object (in order to get rid of @s) makes every variable accessible
from outside the object. therefore the data is not encapsulated any
more.

so what you get is the encapsulation of a variable within an object
and at the same time exposing it to the rest of your system. (of course
you could set your accessors private, but that’s even more code.)

g phil

On Feb 12, 2008, at 8:50 PM, Philipp H. wrote:

accessors are meant to make the instance variables of an object to be
accessible from outside. creating accessors for every variable used in
an object (in order to get rid of @s) makes every variable accessible
from outside the object. therefore the data is not encapsulated any
more.

I’m afraid you’re confusing encapsulation with information hiding [0],
especially as it pertains to inheritance. Both are good tools when
used in the right context, but they are not the same. You do not
“break” your code every time you use one of the attr generator
methods. Instead you provide an interface to some information that
your class/instance provides. You’re not opening a vault and letting
everything run crazy/chaotic by providing access to those instance
variables. Instead, you’re providing a clean and orderly way of
getting at that data[1].

Providing accessor methods is the only sane way to make your code and
its subclasses more resilient to change. It allows you to change the
internals without affecting the subclasses that use that interface.
Classes that use ivars directly are more brittle and require more work
to maintain.

From Beck’s Smalltalk Best Practices:

If you need to code for inheritance, use Indirect Variable Access.
Future generations will thank you.

One warning–do not go half way. If you are going to use direct
access, use it for all access.

[0] http://c2.com/cgi/wiki?EncapsulationIsNotInformationHiding
[1] As I’ve said before, if it is anywhere in ruby and evaled or
parsed in any way, I can get my hands on it and manipulate it. If that
scares or bothers you, you’re using the wrong language.

On Wed, Feb 13, 2008 at 1:09 PM, Philipp H. [email protected] wrote:

confusing something. :wink:
that is in fact a good point. i wasn’t aware of that. and might make me

I totally agree. But it still makes a difference for what reasons
e.g. ‘send’ is used. It’s on thing to use it for some nifty
metaprogramming but it’s another to exploit it to access an otherwise
(maybe for a good reason) unaccessible object.

This is one of those topics which got me writing again:

http://talklikeaduck.denhaven2.com/articles/2008/02/15/best-practice-patterns-accessors-and-encapsulation


Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/

On Wed, Feb 13, 2008 at 05:51:33PM +0900, Ryan D. wrote:

I’m afraid you’re confusing encapsulation with information hiding [0],

i don’t think so, but thank for pointing me to that article. without
reading it, i would have thought: hm, presumably he is right, i’m
confusing something. :wink:

Providing accessor methods is the only sane way to make your code and
its subclasses more resilient to change. It allows you to change the
internals without affecting the subclasses that use that interface.
Classes that use ivars directly are more brittle and require more work
to maintain.

that is in fact a good point. i wasn’t aware of that. and might make me
change my mind. could you or anyone else point out a problamtic case
in few lines of code? just curious.

[0] http://c2.com/cgi/wiki?EncapsulationIsNotInformationHiding
[1] As I’ve said before, if it is anywhere in ruby and evaled or parsed
in any way, I can get my hands on it and manipulate it. If that scares or
bothers you, you’re using the wrong language.

I totally agree. But it still makes a difference for what reasons
e.g. ‘send’ is used. It’s on thing to use it for some nifty
metaprogramming but it’s another to exploit it to access an otherwise
(maybe for a good reason) unaccessible object.

g phil

On Feb 15, 2008, at 09:01 , Rick DeNatale wrote:

This is one of those topics which got me writing again:

http://talklikeaduck.denhaven2.com/articles/2008/02/15/best-practice-patterns-accessors-and-encapsulation

Nice writeup.

It was also nice to see you referenced in Kent’s book. :slight_smile: