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
on 01.02.2008 18:54
on 01.02.2008 19:05
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 01.02.2008 19:07
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/
on 04.02.2008 03:18
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 04.02.2008 10:58
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"?
on 04.02.2008 11:00
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. :P
on 13.02.2008 05:51
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"? 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 13.02.2008 08:21
Philipp Hofmann 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 Williamsson
on 13.02.2008 09:53
On Feb 12, 2008, at 8:50 PM, Philipp Hofmann 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 13.02.2008 19:10
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. g phil
on 15.02.2008 18:02
On Wed, Feb 13, 2008 at 1:09 PM, Philipp Hofmann <phil@s126.de> wrote: > confusing something. ;) > 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 15.02.2008 21:20
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. :)