@var = change to accessor method? Why?

D

Day

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
 
S

Sebastian Hungerecker

Day said:
So... what's the advantage of changing

class Thing
=A0 attr_accessor :a

=A0 def do_something(arg)
=A0 =A0 @a =3D arg
=A0 end
end

to...

class Thing
=A0 attr_accessor :a

=A0 def do_something(arg)
=A0 =A0 self.a =3D arg
=A0 end
end

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

HTH,
Sebastian
=2D-=20
Jabber: (e-mail address removed)
ICQ: 205544826
 
A

ara howard

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



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/
 
P

Philipp Hofmann

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
 
R

Ryan Davis

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"?
 
R

Ryan Davis

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. :p
 
P

Philipp Hofmann

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
 
J

Jari Williamsson

Philipp said:
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.

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 Williamsson
 
R

Ryan Davis

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.
 
P

Philipp Hofmann


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. ;)
...

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
 
R

Rick DeNatale

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. ;)
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.

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

http://talklikeaduck.denhaven2.com/...practice-patterns-accessors-and-encapsulation
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top