DEV Community

Cover image for “I monkey patch from time to time.”- A proposal on how to deal with a bad habit.
Simon Meyborg
Simon Meyborg

Posted on

“I monkey patch from time to time.”- A proposal on how to deal with a bad habit.

Should I let you in on a secret? ‘I monkey patch from time to time’. Uhh. Okay, it’s in the title. You clicked. So I guess you do so as well, right? We Rubyists all do from time to time I guess.

And we all know it’s bad whether because we know exactly why or just on a gut level.

So let’s first address the topic to the small head-scratching minority.

According to Wikipedia, a “Monkey patch is a technique used to dynamically update the behavior of a piece of code at run-time.”

If you are taking part in such activities, you can experience side effects. Wikipedia is also quick to address this:

  • They can lead to upgrade problems when the patch makes assumptions about the patched object that are no longer true; a new release may very well break the patch. For this reason monkey patches are often made conditional, and only applied if appropriate.

  • If two modules attempt to monkey patch the same method, one of them (whichever one runs last) “wins” and the other patch has no effect, unless monkey patches are written with a pattern like alias_method_chain.

  • They can be written with malicious code in order to attack the main program, or each other.

  • They create a discrepancy between the original source code and the observed behavior that can be very confusing to anyone unaware of the existence of the patch.

  • Uugh. That’s not good. But hey, remember the subtitle? I promised you to have something against this.

Let’s start with the last pitfall — losing track of what you have overridden/patched.

Wouldn’t it be great to have something that just shows you what methods in your code base have been patched?

The awesome reflective capabilities of rails allow this. I wrote a small gem that hooks into a loading application, bookkeeps every class and its methods, and then once the application has fully loaded checks again to see if the original implementation still is the one that’s in charge.

If not, it‘ll show you which is now.

Terminal output of the overrides_tracker gem’s tracking

That gem is called ‘overrides_tracker’. Should have called it something more funky like “monkey catcher”, but that’s a different topic.

So okay, now you know what you or others have patched — maybe even outside your codebase like in GEMs you use. Fine. What about the other three points on that list?

As mentioned on Wikipedia a monkey patch can degenerate over time. You might not touch your patch but the code you overrode can change with every jump in a GEMs version, sometimes even by other gems suddenly deciding to patch that particular method.

Overrides Tracker has the capability to compare your monkey patches across branches. So you can easily check whether some underlying code has changed or if your override still is in charge.

Terminal output of the overrides tracker gem’s comparison.

Okay, awesome. But checking this every time you upgrade an application can easily be forgotten. So that’s why I build a small service that takes care of all that and that hooks into your CI/CD Pipeline. It’s called overrides.io. It’s a way nicer interface than your terminal window. It provides a side-by-side comparison of all your patches and the original method. Plus, you can easily copy the path to your clipboard to quickly find it using your editor.

Overrides.io: Overview of all your monkey patches of a specific build.

Its real magic lies in the comparison of your builds. Whenever a change in your method or the original occurs, you will be notified via email. From there we take you immediately to the comparison of the builds, so you can inspect what has changed. We make things even easier by highlighting the lines for you.

Overrides.io: Comparison between two builds.

So don’t stress yourself about your monkey patches. Delegate the work of monitoring those to overrides.io and sleep better.

Top comments (0)