🐵What is monkey patching?
A monkey patch is a way to change, extend, or modify a library, plugin, or supporting system software locally. This means applying a monkey patch to a 3rd party library will not change the library itself but only the local copy of the library you have on your machine. The term monkey patching refers to changing code at runtime. This may be done as a workaround to a bug or a feature. No software can be totally free from bugs. Sometimes with a major update, little bugs that are not that devastating creep into the software but make our work more difficult.
Though, this does not mean monkey patches are only used in case of bugs in the library or code we are using. It can also be a means to change some behavior that does not do what we desire. Like a console log that has been left in production or that one function that should be returning integers instead of floating-point numbers. It is possible to make changes to the code using monkey patching.
However, this only applies a patch to the original code. It does not affect the actual code, but only your copy of it. This means if you installed a math library using npm, a monkey patch will only affect the library for you, it won't change the library npm has.
😈Why is it considered evil?
Monkey patching is not a unique technique. It is not "evil" per se. Any technique irresponsibly used can be considered evil. There are other ways to solve problems that can be solved by monkey patching. There are very rare cases where monkey patching may be the only solution. That is why, there are so few situations where monkey patching is required, that it is considered evil by developers.
Patches made to a module might not work after the module is updated and some methods are changed. This might create a major bug or cause the website/app to crash depending on the patch applied and the changes made to the module. So if the patches are not applied conditionally, it can lead to unfavorable outcomes.
If two or more components/modules apply a monkey patch to the same method, depending on which component/module runs last, the other monkey patch will be meaningless.
Monkey patches can be very confusing to someone who is not aware of them. Differences between the installed module and the actual behavior of the source code can lead to frustrated developers.
🤔Should you use it?
It all depends on your preference. If the situation calls for it, then you should use it while making sure to avoid common pitfalls. Though you will probably go through your entire career without facing a situation where you would need to use it, if you find yourself in one, now you know there's a solution for that pesky problem.
Top comments (6)
I've used this a few times. For my hobby projects, I use D. Its main dependency and build tool (dub) doesn't download pre-compiled libraries, but rather the source code, and builds the library from there. Which means that you can actually edit the dependent source and get your own version of the library. I've done it a few times, mainly to try to fix a bug or investigate suspicious behaviour.
In our production code base we ran into problems like that as well. Our solution was to copy the source for a bugged class into our own project and fix the bug locally. Fortunately, this was a top-level class which we were able to swap out rather painlessly. In a different project, we made our own fork of a library and changed its internals to our needs.
I think TBH that locally monkey pawing should be avoided. Projects should work 'out of the box' as much as possible to reduce errors and frustration, as you've mentioned. Also, as we found out, forking the code means that we were also responsible for the maintenance.
Totally agree!
Could not agree more! @ben and I were just discussing monkey patching on one of my recent blog posts, The Importance of Knowing Your Gems
An interesting conversation. I liked the method you mentioned to Ben about monkey patching some changes and then issuing a PR to the repo. That's a good use for monkey patching, but I'm guessing it's not always the best solution. I have yet to start working as a developer so I may not have much work experience, but I have not yet seen a good use for monkey patching. Even the times when you used monkey patching, they were temporary changes.
Also, some good points in your blog! Although I am not a Ruby developer, it's advice worth keeping in mind.🙂
I think it’s easy to stumble in to monkey patching. I remember building a WordPress template once, and I couldn’t figure out how to change something specific — something that wasn’t immediately obvious from googling. A senior recommended I just search all the files in the source code for the string that made it up, and change it. I was just a junior, but it felt dirty to wrestle in the source code, even though I didn’t have any idea of how to accomplish the thing I wanted.
Of course nowadays I realize there’s a hook in WordPress for nearly everything.
Yep, that can be a bit overwhelming if you're not used to it. Sifting through a ton of code for a specific thing is too much for those doing it for the first time.