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.
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.
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 Sat, Feb 02, 2008 at 02:54:04AM +0900, Day wrote:
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.
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 Mon, Feb 04, 2008 at 06:57:21PM +0900, Ryan Davis wrote:
On Feb 3, 2008, at 18:18 , Philipp Hofmann 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"?
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.
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
···
On Mon, Feb 04, 2008 at 06:57:21PM +0900, Ryan Davis 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 Feb 12, 2008, at 8:50 PM, Philipp Hofmann 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.
...
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 Wed, Feb 13, 2008 at 05:51:33PM +0900, Ryan Davis wrote:
On Wed, Feb 13, 2008 at 1:09 PM, Philipp Hofmann <phil@s126.de> wrote:
On Wed, Feb 13, 2008 at 05:51:33PM +0900, Ryan Davis 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.
> ...
>
> 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.