The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Best Practice Patterns, Accessors and Encapsulation

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Rick DeNatale

Posts: 269
Nickname: rdenatale
Registered: Sep, 2007

Rick DeNatale is a consultant with over three decades of experience in OO technology.
Best Practice Patterns, Accessors and Encapsulation Posted: Feb 15, 2008 9:29 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Rick DeNatale.
Original Post: Best Practice Patterns, Accessors and Encapsulation
Feed Title: Talk Like A Duck
Feed URL: http://talklikeaduck.denhaven2.com/articles.atom
Feed Description: Musings on Ruby, Rails, and other topics by an experienced object technologist.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Rick DeNatale
Latest Posts From Talk Like A Duck

Advertisement

Kent's Autograph to me on STBPP One of the classics in the Smalltalk literature, which has also had a big influence on the Ruby community is Kent Beck’s “Smalltalk Best Practice Patterns”, which captures the best practices for designing and coding Smalltalk programs. Back when it was published, I used to see Kent a few times a year, and happened to be in the Bay area when he made an author appearance at the Computer Literacy Bookstore in San Jose, where I got my copy, and the autograph shown here.

The Ruby language has many similarities with Smalltalk, so much of Kent’s advice applies to Ruby. I frequently hear prominent Rubyists mention the book.

On the other hand, Ruby is not exactly Smalltalk, so Kent’s book isn’t an exact fit to Ruby. I’ve been wanting to start writing about adapting some of these patterns to Ruby for a while, so this article will hopefully be the first in a series.

The Motivation For This Article

Recently on the ruby-talk forum a thread discussing accessor methods vs. direct instance variable access came up. This was a hot debate topic in the Smalltalk community back in the 90s, and Kent addressed it in two competing patterns in the book, one of which Ryan Davis (a.k.a ZenSpider) brought up in the conversation.

Patterns Are Decisions, Not Prescriptions.

In their best form, patterns represent a network of decisions made during the creation of something, in this case software. A good pattern should describe the forces which affect the decision whether or not to adopt the particular solution it offers.

There can often be a tension between competing patterns, different patterns optimize different desirable characteristics, such as readability vs. flexibility.

The forces, or their relative strength, can be affected by technical factors such as the language, and features of the editor or IDE being used. To varying degrees many or all of Kent’s Smalltalk patterns have forces affected by the capabilities of the Smalltalk IDE. One of Kent’s main goals is readable code, so writing code to maximize the utility of the code exploration features of the Smalltalk browsers, inspectors, and debugger figures into the book.

A Tale of Two Patterns

Now to the specifics of the article at hand. The book has two patterns described in sequence,starting on page 89, “Direct Variable Access”, and “Indirect Variable Access”. Both address the same problem “How do you get and set an instance variable’s value?” and give two opposing solutions, along with a good discussion of the tensions.

The first pattern, as the name implies, advocates referring to an instance variable directly by name, so in Ruby, within a method, you’d just write @x, instead of using accessor methods, the second pattern.

As Kent points out in the discussion of the first pattern, direct vs. indirect access was a hotly debated topic in the Smalltalk community, although indirect access got to be popular since it was advocated by several Smalltalk training companies.

Tension Number One: Readability

In his argument for direct variable access, Kent explains that whenever he ran into an accessor method invocation, which in Smalltalk looks like this:

a = self x

He found himself pausing to remind himself that x was “just” accessing an instance variable, but that he would read the direct form:

a = x

without breaking his stride.

I might point out that Ruby is subtly different here. First, direct instance variable access is clearly marked with the ”@” sigil. On the other hand, a read accessor invocation in Ruby can be written without the explicit self receiver:

a = x

So it’s not as clear that this is a method invocation as opposed to a local variable access, although we know that it isn’t a direct instance variable access. Write accessor invocation usually requires an explicit receiver:

self.x = a

to disambiguate between a write accessor call and simply assigning to a local variable, at least the first time x appears in a particular lexical scope.

Tension Number Two: Subclassablity

Although direct instance variable is more readable, it does have a drawback in that it makes certain subclassing patterns harder to implement.

If a class uses indirect variable access consistently, then a subclass can leverage this by overriding the accessor. For example, lets say we want a subclass which audits changes to an instance variable. By overriding the setter accessor it can do things like logging changes very simply. Otherwise any methods which access the instance variable in the superclass need to be overridden.

Kent’s example is defining a PolarPoint subclass of Point which has radius and theta instance variables, and overrides Point’s accessors for x and y. One interesting aspect of the Ruby/Smalltalk comparison when you look at this example a little more deeply relates to my recent article about instance variables. In Smalltalk since the Point class has x and y instance variables, it’s subclass PolarPoint would have x, y, radius and theta instance variables, although the x and y variables would be vestigial and unused. In Ruby a PolarPoint instance wouldn’t acquire the unneeded x and y instance variables.

The Encapsulation Tension

One of the reasons why there was/is such a debate between proponents of direct vs. indirect instance variable access is the effect providing setter and getter accessors has on the apparent encapsulation of the object’s state.

First, in either Ruby or Smalltalk, the mere absence of accessor methods doesn’t prevent encapsulation intrusions. Ruby has the instance_variable_get and instance_variable_set methods, and Smalltalk has instVarAt: and instVarAt:put:, but these methods are ‘marked’ as slightly evil and reserved for dastardly deeds.

An accessor method on the other hand seems much more like any other normal method. In Smalltalk, convention is used to mark methods as private, although this is very weak consisting simply of putting private methods in a particular category in the browser, with no runtime check. Ruby does provide runtime checking of both private and protected methods, although even this protection can be circumvented, using send.

Summing Up

So in the end, the existence of and the tension between these two patterns demonstrates some key points:

  • Patterns present choices, and the best patterns provide enough information to make an informed decision on a case-by-case basis.
  • The languages and the tools we use have an effect on the patterns and the decisions they engender.

Read: Best Practice Patterns, Accessors and Encapsulation

Topic: Vancouver.rb Subversion Repo @ RubyForge - Share Your Ruby Scripts with the World Previous Topic   Next Topic Topic: Gems Server

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use