From: Chris Date: 2010-06-19T21:01:37+09:00 Subject: Re: Getting rid of self - OT On Thu, 17 Jun 2010 06:29:37 +0900 Josh Cheek wrote: > On Wed, Jun 16, 2010 at 2:56 PM, Rick DeNatale > wrote: > > > On Wed, Jun 16, 2010 at 3:23 PM, Josh Cheek > > 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: http://github.com/rubyredrick > > Twitter: @RickDeNatale > > WWR: http://www.workingwithrails.com/person/9021-rick-denatale > > LinkedIn: http://www.linkedin.com/in/rickdenatale > > > > > Thanks for the explanation, Rick. I've thought about it a bit, and I > think for me, that using indirect access is the better choice in most > situations (there are some situations where I use direct access, such > as setting state for a view in Rails). I certainly take Kent's advice > very seriously, though I'm curious whether his opinion is the same > for Ruby as it is for Smalltalk. I also agree with you regarding > subclassing, I'm having a hard time thinking of a situation where a > subclass works that a module doesn't. In "Refactoring - Ruby Edition" (with Kent Beck) the consensus seems to be: choose whatever fits your needs and refactor when the requirements change. (who would have guessed something like this from a book with that title *g) Chapter 8. Organizing Data > Self Encapsulate Field - Pg. 188 I highly recommended the book, especially for non Smalltalkers. And while speaking about rewritten books for Ruby, i just finished "Design Patterns in Ruby" and found it very enlightening, too. Sry for OT'ing Greets, Chris