Concepts of programming languagesJavascript

What About Monkey Patching? Is it as Dangerous as They Say?

Monkey patching is modifying a third-party class. It’s a great tool, coming in handy all the time. Only it’s frowned upon by the experienced programmers. Should you adopt or abandon monkey patching?

Let’s have a look at some useful applications of monkey patching first.

Why is monkey patching useful?

My favorite example is written in the Groovy language. It combines monkey patching and the fact that even simple integer numbers are objects in Groovy. So you can add methods like mile(), km(), meter, and probably even ångstrøm() to the Double class and write code like this:

// Java-like coding style:
System.out.println(1.mile() + 500.meter());

// equivalent, more relaxed coding style:
println 1 mile + 500 meter

When I was writing software for the financial industries, I missed this feature badly. It’s hard to calculate with money and currencies if you have to convert everything to an object first. Just try to jot down a formula with simple numeric values, and repeat the same exercise with Java’s BigDecimal again. You’ll notice the difference painfully.

Other use cases of Monkey patching

Actually, Monkey patching refers to two slightly different ideas:

  • You can augment an existing class. You can add methods and attributes. That’s what we did above when we added meter() to the Double class.
  • You can modify a method of an existing class.

At first glance, the second idea is irresistible. Do you have to work with a third-party library that’s buggy? With monkey patching, that’s not a big deal. Just apply a Monkey patch to it, and it’s as good as new.

Risks of patching a third-party library

There’s a catch. What happens when the bug of the third-party library has been solved? If you’re lucky (or well organized), you remember to remove your patch. But there are no guarantees.

Actually, that’s also true with other workarounds, such as encapsulating the offending library in a class fixing the bug. The problem with Monkey patching is that it also affects the code using the offending library directly. This may include code written by your co-workers in the neighbor department and even other third-party libraries.

Basically, that’s already the morale of the story. Monkey patching is a tool that’s just a bit too powerful. It affects everything, including uses you didn’t think of at the time of writing.

But adding functionality is good, isn’t it?

Another popular use of Monkey patching is adding methods to existing classes. For instance, until ECMAScript 2015, there was no string.contains() method. Luckily, that’s no problem with JavaScript, so many libraries stepped in and filled the gap. For example, the popular Mootools added this method. It was a good idea, so the library went viral.

In fact, it became so popular that the ECMAScript team decided to rename their contains() method to includes(). If they were to add their own implementation of contains() amounts to breaking zillions of existing websites. The semantics of the ECMAScript specification differs slightly from the Mootools implementation. Plus, the Mootools have been implemented in a conservative way: it only adds contains() if it isn’t already there. That sounds like a good idea: there’s no point in patching a method that’s already been patched. However, in combination, these two facts would break existing code. It’d be better if the Mootools simply overwrote the new ECMAScript method.

In this particular case, Monkey patching even interfered with the development of the programming language.

Weird errors

You get the gist of it. Monkey patching is a powerful tool, but it’s just a bit too powerful. If you need it, think again. You’re about to add non-standard behavior to your code base. That’s exactly the kind of surprises you’d rather avoid. Your co-worker who’s going to maintain your code next year will love you for that.

Other developers have the same idea

Another risk is that other programmers probably had the same idea. If you’re Monkey patching a method, chances are one of the libraries you’re using also patches the same method.

Which implementation is going to be executed? More likely than not, that’s unpredictable. Plus, if you’re patching a method that’s patched by someone else, too, their patch isn’t applied. So the third-party library you’re using probably breaks.

When to use Monkey patching – and when not to use it

I’m pretty much convinced Monkey patching is such a powerful tool you shouldn’t dismiss it. Granted, the reason why it’s part of languages like JavaScript and Ruby is just a side-effect of the language design. But there’s a reason why it has been added to languages like Groovy and C#. So here’s my list of suggestions:

  • Never use Monkey patching in a library.
  • Never use Monkey patching to repair a third-party library.
  • If you can’t avoid patching a third-party library, do it in a careful way. Scream it out in your documentation, mention it in the log files, and add a version check. Even so, it’s a risky game.
  • On the other hand: if you’re a solo programmer in a short-lived project, go for it!
  • The same applies if you’re reasonably sure you’re additions will never interfere with any third-party library or the future versions of your programming language. There’s no way to be sure, but I’d wager adding currencies, mile(), and meter() is on the safe side, just to name a few examples.
  • But again, think twice. The reason why I’ve written this article is because I’d like to Monkey-patch the JavaScript methods console.log(), console.error(), and so on. I’m sure there’s more benefit than risk. But when I investigated for this article (and the task at hand), I learned that many other programmers had the same idea, and it didn’t pay out for all of them.

Wrapping it up

Monkey patching is like a drug. At first glance, it’s obviously the way to go. There are side effects, but they tend to show up a year or two later. So think twice before applying a Monkey patch.

But then – it’s true that sharp knives cut, but tell this a surgeon. There’s a place and a time for everything!

Dig deeper

Gilad Bracha on Monkey patching
Aurelio de Rose on Monkey patching
Wikipedia on Monkey patching (regard the “pitfalls” section)
Pragmatic uses of Monkey patching by Vildan Softic
Monkey patching for mere mortals