Introducing private_attrs

Zach Colon
Adwerx Engineering
Published in
3 min readMar 29, 2018

--

A simple solution to an ugly problem

There is a growing trend among rubyists to avoid referencing instance variables directly, and instead encapsulate these variables in getter methods. Ruby already implements this pattern using attr_* methods, but there is no current option to make private readers, writers, and accessors.

Creating private getters and setters prevents future misuse of an object by accessing internal variables that were not originally part of this object’s public API. Also, it prevents littering the code with instance variables which allows for better readability.

The private_attrs gem is a small addition to Ruby’s Object that allows for defining private attribute methods.

How is this solution different from existing patterns?

There are a few options to accomplish this behavior without introducing this gem. But they each fall short in one category or another. The example below violates the ‘Scissors Rule’ of coding in that there is not a clear separation between public and private methods. The little known principle was espoused by Robert C. Martin in his book, Clean Code.

This next example is better as it doesn’t violate the scissors rule, but still not ideal. As a reader and writer of Ruby, I have come to expect that all attr_* definitions occur at the top of a class. If this model was particularly large, I might miss this definition completely!

Other patterns are even worse as they become overly verbose and offer poor readability. Consider the following example that mixes public and private attrs methods. Do you find it easy to read and understand?

Here’s where the private_attrs gem comes in. The library allows for the easy definition of private attr_* methods while maintaining readability. Its use dodges the pitfalls of the previous examples by obviating the need for public/private context switching, allowing for all attr_* method descriptions to be included where we expect them, and doing so in a clean manner consistent with Ruby’s included attr_* methods.

In summary, the existing patterns to add private attribute reader/writer methods lend themselves to poor readability, and definitely contribute to some raised eyebrows during code review This library adds the ability to keep code clean and readable while also keeping the API of the class as closed as possible.

Enjoy!

--

--