post_initialize

Elegantly kicking ‘super’ to the curb with hook methods


‘Super’ seems like an innocent enough technique to share methods between class and superclass. But a closer look reveals that simply by using ‘super’ you are forcing a subclass to “know” its superclass’s methods. And this “knowing” is just an unnecessary dependency.

Let’s look at a simple example of ‘super’ in the initialize method:

Cat & Tiger inherit initialize from Felidae

It may not seem like much, but there’s clearly a dependency hiding in that code. The subclasses’ initialize methods assume their superclass has an initialize method.

How can we clean this code up?

Now Felidae holds all the power

This simple refactor achieves two simple things: (1) it shifts all initializing power to Felidae, and (2) it allows Cat and Tiger to remain oblivious to the inner workings of their superclass.

So when a new Cat is called with ‘initialize’, Ruby will first search the Cat class. Not finding ‘initialize’ there, it will search its superclass — Felidae.

Finding ‘initialize’ in Felidae, the new Cat instance will receive its instance attributes from that method. Then when Felidae’s ‘initialize’ calls ‘post_initialize(args)’, Ruby will find that method within the Cat class and run it. (‘self’ in this context is the new Cat instantiation)

And there it is. Subtle yet powerful. Destroying one dependency at a time.

Email me when Austin Sprawls publishes or recommends stories