The Case Against Monkey Patching
shopify.engineering
shopify.engineering
The Stallman-era idea of taking possession of your own copy of open source code so that you can do with you want with it, is now being argued to be too dangerous for you.
You should just trust the upstream team, just like you would with proprietary software, and if you reaaally need something custom, you should let them take a look at your idea in a PR and they’ll decide if it’s a good idea that can be merged when they’re ready to schedule it in.
When you look at the security risks and developer talent at play today, you can understand why this argument makes some sense. But if you’ve watched or been part of the of the Open Source Revolution, you kinda have to laugh at the irony.
IMO, and I suspect RMS would agree: defadvice shouldn't be used in code you distribute to others, because multiple pieces of advice can conflict, and the code defining the advice doesn't control which advice is loaded first. It is still a valuable tool for usage in personal configuration and for prototyping.
I don’t use Ruby, but I have had to monkeypatch a lot in Java and literally every time I would have preferred not to, but did it because I had to.
I once had a fun conversation with a head of product for some software once where he said a monkeypatch is ok for a spike when you’re testing something but you should never monkeypatch in production and I explained I had 14 monkeypatches to his product currently in production and you couldn’t even log in with ssl to his product without monkeypatching out some parts of the SSL cert verification code because the cert verification wouldn’t work with certs issued by an enterprise CA (rather than a trusted root CA).
In all of these cases these were patches that had been submitted upstream that I didn’t want to have to maintain but had been rejected by upstream because my use case wasn’t what the dev thought the general use case was. That’s fine btw and exactly why monkeypatching is useful.
On the other hand reasonableness is in the eye of the beholder.
As both user and victim of monkeypatches, i’d rather nobody had to but there’s not always an agreement to be found (or feasible at all).
On that point I like Cargo’s support for local versions / forks of dependencies, it provides a cleaner and less fraught support for patching your upstream (whether you ultimately fork or not).
Typescript is my language of choice because of its full stack flexibility and amazing tooling support because of typing. If you think typing systems are too confusing you're definitely not qualified to write monkey patches in an untyped language. Typing reduces minor bug iterations by 90%+, major bugs immensely, and ultimate development resources by 90%+.
One person can maintain a huge Typescript app with just basic tests. You need a teams of people to maintain 50x the number of tests and fix obscure bugs with any Ruby app.
I'm not even sure an AI could refactor a Ruby app properly, but Typescript any human can.
FB devs wrote millions of lines of PHP/Hack code when it was untyped, and then it gradually became more and more typed, and they had to keep modifying the entire codebase with various elaborate schemes so that it sort of complies with increasingly strict type checking. A lot of that was inserting compiler directives to say "ignore type errors on the next line." That built up tech debt which eventually had to be dealt with, and doing that is soooo much more difficult than writing typed code in the first place.
At the end of the day, the job needs to get done. Sometimes this involves modifying existing things for a particular purpose.
But it’s a wonderful, powerful tool to have in the toolbox, when used sparingly.
I wonder how much of the pain of monkey patching could be partially explained through the way that large companies maintain (or don’t maintain) their codebases? In my experience code is often hard to maintain because of a lack of continuity, context, and support from an employer to actually do the maintenance. In that world, monkey patching is an extra-special kind of hell.
I wonder sometimes if we might all feel less strongly about monkey patching if we had more time to care for the code we write.
…Rails is really a product of its time and no-one should be using it almost 20 years after that.