Using instance variables vs attribute accessors

In our discussion today we were originally evenly split between people that generally use attribute accessors for private state and those that use instance variables directly.

** Attribute Accessors: **

  • PRO: Uniform access. Refactor to the method (add memoization, etc) is done in a single place.
  • PRO: Typo protection. Typos of a method give a more obvious error (and are guaranteed to error). Typos of an instance variable don’t error. You may get a test failure, but the error won’t be as obvious.
  • PRO: Accidental assignment is more difficult (only possibly if you also have a private attr_writer as well).
  • CON: Using attr_reader in private scope warns when running ruby with warnings (ruby -w). Can either live with it (who runs with -w, anyway?), write the reader by hand, or use attr_extras.

** Instance Variables: **

  • PRO: Makes state dependency obvious at a glance (syntax highlighting)
  • PRO: You know immediately that accessing an instance variable is not expensive (no db read, etc).
  • CON: If you need to introduce a reader at a later date, the refactor is simple, but much wider (file, possibly any included modules)

We spent some time wondering why it is that ruby would opt to silently return nil when a previously undefined attribute is accessed. If a warning or error was raised you’d at least be alerted to typos.

We also discussed the pros and cons of the attr_* macros. These really apply to all uses - be they private or public. That is, attr_* yield methods that are difficult to grep for and are not understood by ctags.

As a group, we couldn’t come to a consensus on which practice should be recommended. No one was particularly swayed from their original position, though one person did say they would probably give attribute readers a try.

The one thing we definitely did agree on was that consistency should be valued above all in this case. Don’t use an attribute reader for some private state but instance variables for other private state in the same class. Be consisten in a class and try to be consistent across a project if that’s feasible.

3 Likes