From: Dave Thomas Date: 2004-11-12T05:53:59+09:00 Subject: Re: ruby idiom for attribute definition? On Nov 11, 2004, at 14:26, Hal Fulton wrote: > Dave Thomas wrote: > >> A class with a large number of attr_accessors is not really an >> encapsulated class > > Now *that* is food for thought. It makes me have second thoughts > about some of my recent code. > > Would you be interested in elaborating on this theme? A class encapsulates behavior and state. It uses that behavior to modify that state. That's important, because it means you have a single place to look when you want to change functionality or fix bugs. Imaging you have class BankAccount. It provides methods such as transfer_to(other_account) and so on. It also exposes the current balance. First let's imagine it's written like this: class BankAccount attr_reader :balance def transfer_to(other_account) ... end end During acceptance testing, we notice that the balance is off by a penny at the end of a (test) day. Where do we have to look for the problem? Well, the only thing that can set the balance is transfer_to() and the other methods of BankAccount. The problem must be in there somewhere. It's bounded, and amenable to unit testing. Now imagine we'd written it as class BankAccount attr_accessor :balance def ... At the end of the day, we have the same problem, Now where do we look? Eek! Everywhere. Any code that sets the balance from the outside is a suspect. We've totally lost the benefits of encapsulation. For this (and for many other reasons), Ruby doesn't make instance variables public. Using attr_accessor and attr_writer is often an appropriate way of circumventing Ruby's shyness. However, these two functions always cause me to think twice when I use them. "What is the potential damage that this breach in encapsulation can cause? Is it worth it?" Cheers Dave