Object Calisthenics in Ruby

Rafael A. George Duval
3 min readJan 11, 2022

Writing better Object-Oriented code in Ruby by following Object Calisthenics.

Object Calisthenics are programming exercises invented by Jeff Bay[1]

Jeff formalized the practice as a set of 9 rules

By following these rules as much as possible, you will change how you write.

These rules focus on the maintainability, readability, testability, and comprehensibility of your code.

The following is my take on following the rules in a Ruby code-base.

1. One level of indentation per method

Too many indentation levels can make a code base hard to follow and understand.

It is often impossible to understand what the code is doing without compiling the code in the head.

In Ruby on Rails applications, the problem is visible in Big ActiveRecord models.

Split methods to follow this rule. The Extract Method Refactoring recipe is useful in this situation.

The first thing that is important to extract is the loop’s body.

At the end of the Refactor, we end up with more code. But, that’s not bad because the optimization is towards comprehension.

The practical benefit of the change is that it makes every method in the class be at the same level of abstraction.

2. Don’t use the ELSE keyword

This is rarely bad. But, I prefer to avoid having an ELSE statement in any method.

A straightforward way to drop it is by using early returns in the method definition.

3. Wrap all primitives and Strings

Following this rule is pretty straightforward. Encapsulate all the primitives within objects to avoid the Primitive Obsession code-smell.

If the variable of your primitive type has a behavior, you MUST encapsulate it. And this is especially true for Domain-Driven Design. DDD describes Value Objects like Money or Hour for instance.

Introducing ValueObject in Ruby is straightforward:

4. First class collections

Any class that contains a collection should contain no other member variables. If you have a set of elements and want to manipulate them, create a dedicated object for this set.

Each collection gets wrapped in its own class. Behaviors related to the collection have a home (e.g., filter methods, applying a rule to each element).

It is easy to add collection behavior to objects in Ruby implementing

The Comparable[2] and Enumerable[3] modules in Ruby add Collection behavior to any object.

5. One dot per line

The rule says that you should not chain method calls.

It is the direct use of the Law of Demeter, saying only talk to your immediate friends, and don’t talk to strangers.

6. Don’t abbreviate

Abbreviations of names often come with good intentions.

Name abbreviation promotes code duplication.

The lack of context in shortest name push programmers to put in place the same logic. The end result is code duplication.

Don’t abbreviate, period.

7. Keep all entities small

No class over 50 lines and no package over 10 files.

The idea behind this rule is that long files are harder to read, understand and maintain.

Is often the case in Ruby on Rails applications that objects become God objects.

Small entities promote encapsulation.

8. No classes with more than two instance variables

This rule is the hardest, but it promotes high cohesion and better encapsulation.

A picture is worth a thousand words, so here is the explanation of this rule in the view. Note that it relies on Rule 3: Wrap All Primitives And Strings.

9. No public access attributes

The last rule is the practical application of Tell, don’t ask.

Passing data around is part of any complex system. Yet, making decisions on data that an object doesn’t own is not.

Conclusion

Introducing the rules to a Ruby on Rails team might be tricky but doable.

Following these rules lead to a manageable code-base. It is worth the investment to apply the regulations. Improving code comprehension will bring many benefits to the team and company.

[¹]: The ThoughtWorks Anthology: Essays on Software Technology and Innovation
[²]: Comparable
[³]: Enumerable

--

--

Rafael A. George Duval

✍🏼 Indie writer, chief editor of https://snippetsoftext.substack.com/ | 💻 Software Engineer | 📊 Tech Leadership