16

I've been under impression, that monkeypatching is more in quick and dirty hack category, rather than standard, good programming practice. While I'd used from time to time to fix minor issues with 3rd party libs, I considered it temporary fix and I'd submit proper patch to the 3rd party project.

However, I've seen this technique used as "the normal way" in mainstream projects, for example in Gevent's gevent.monkey module.

Has monkeypatching became mainstream, normal, acceptable programming practice?

See also: "Monkeypatching For Humans" by Jeff Atwood

dodgy_coder
  • 1,098
  • 7
  • 22
vartec
  • 20,760
  • 1
  • 52
  • 98
  • 13
    I would say that something named **monkey** patching is **NOT** considered good programming practice. Without even knowing what it is, just by the name of it. – littleadv Apr 16 '12 at 10:05
  • What if 3rd party does not want to do the fix you need? –  Apr 16 '12 at 10:12
  • 1
    @Thorbjørn: good question, on one hand I don't like monkeypatching, on other I don't quite like idea of cloning project and keeping local patches if it's just a minor issue. – vartec Apr 16 '12 at 10:20
  • 1
    @littleadv: ...then call it "hot fix" / "on-the-fly fix" or "runtime fix" and it sounds good right? ;) It's all the same. – dagnelies Apr 16 '12 at 13:27
  • 3
    javascript is pretty much built around the concept – ZJR Apr 16 '12 at 23:42
  • Just to clarify: do you mean the definition of “monkey patch” specific to Python (synonym of “hotfix”) or the much more general definition as used by Ruby? The answers seem to differ on that. Notice that if you use Ruby’s definition then there’s nothing patchy about this, despite the name. – Konrad Rudolph Apr 18 '12 at 10:25
  • For code that is generating revenue, hotfixes are an absolute necessity. The academic world will likely disagree, but most of that world isn't losing $1,000 for every minute that a bug exists in production. The best hotfixes are the ones that the project administration immediately schedules time to undo and fix correctly...but from what I've seen that is rarely the case. – Luke A. Leber Oct 30 '16 at 04:52

5 Answers5

19

No, but sometimes monkeypatch is a lesser evil (than having broken code :)). My general rules for monkeypatches in ruby are:

  • have a really good reason for monkey-patch (temporary critical hotfix is a good reason. Nice formatting of to_s method is not, unless you're working on ActiveSupport)

  • make them as transparent as possible: put them into specific place in codebase and separate files, write documentation describing the reason for monkeypatch (here's an example).

  • easy to remove - documentation should include info about removal and what to watch for. Lots of monkeypatches are temporary, so they should be easy to remove.

Lukas Stejskal
  • 1,404
  • 1
  • 10
  • 15
11

Yes, monkeypatching is very useful!

Somehow, names seem to be highly influencial on people's perception. Call it "monkeypatch" and it sounds bad, call it "hot fix" or "on-the-fly fix" and it sounds good.

Independently of that, I think the capability to alter methods/attributes/functions at runtime is a very useful thing. Even javascript people use it all day long without perhaps knowing it.

For instance:

button.onclick = function(e) { ...}

This simple line illustrates the fact that you alter the behavior of button. It was designed that way. Likewise, you could alter every other function but it would be silly to do so.

Now, for the question of delivering patches that way... well... why not. You just have to download a small patch instead of a big release. Heck, you could even patch a server without stopping it, great! And then, one day, you could also fetch the latest release for a bigger update. Fair enough. So yes, I vote for "runtime patches" as a good thing.

Interestingly enough, some languages like Erlang were even build around this concept. The capability to update a server on the fly.

Of course, in the end, and like with everything else, it's a matter of how you use it. You can make wonderful OO stuff and shitty one, it's all the same.

EDIT:

Let me add some case distinction, whether you are patching your own library or a third-party one.

...basically, what you do with such a patch is fixing a bug of your own or a third party library. In either case it's useful. For your own, it enables you to deliver a fix on-the-fly. For a third-party one, either you wait (several months?) until they fix it by themselves, or you do it now on your own. (you can still submit them the patch, so that they will fix it on their side). When they release their next lib version with the issue fixed, you can still, if you want update the library and remove the patch on your side.

Now, of course, if you use a patch to alter the behavior of a lib and alienate its purpose/way of working, then obviously that's a recipe for disaster. Even a monkey would see that ...well, I hope. ;)

dagnelies
  • 5,415
  • 3
  • 20
  • 26
  • 1
    Nobody says it's not useful. However, it's not a good practice in general. And "hotfix" and "on-the-fly fix" doesn't sound any better to me. – Lukas Stejskal Apr 16 '12 at 13:43
  • 1
    Well, I find the capability of altering the behavior of an application on the fly very useful, even more if it is big one. Heck, you could even have the code storing the old method as backup and a command to automatically rollback on demand! The possibilities are tremendous! – dagnelies Apr 16 '12 at 13:56
  • I agree that it's a powerful and useful feature. But also very dangerous (esp. in Ruby), therefore it should be used with extreme caution (esp. for modification of standard and 3rd party libraries). Have you ever tried to maintain application depending on several monkeypatched 3rd party libraries? A recipe for disaster whenever you try to update some library. – Lukas Stejskal Apr 16 '12 at 16:08
  • 1
    Yeah, I agree, if you use these patches carelessly, in unintended ways or abuse of them, it can quickly become messy. Like you can abuse any concept or make a mess with anything. However, otherwise, if they are well organized and transparent, and they all flow in the next big release, it looks clean to me. ...however, I have no experience with ruby libraries which are heavily patched. – dagnelies Apr 17 '12 at 07:22
  • ...I added some comments on the latter case. – dagnelies Apr 17 '12 at 07:40
  • "I find the capability of altering the behavior of an application on the fly very useful" So do I, and there are lots of good, established patterns for that. If something is supposed to be changed, architect your program accordingly. Don't subvert the architecture. – weberc2 Sep 23 '15 at 15:48
8

I believe that all patches are inherently risky due to their run-time nature, and inability to be caught at design-time.

They welcome runtime exceptions, and require complex debuggers and watches just to follow.

They are used when people SEAL classes, and so inheritance is impossible. However, there are better ways to extend objects without damaging them.

My two cents

4

Patching in general should be a last resort, monkey patching even more so. The issue is primarily one of maintainability.

A long time ago, my linux kernel had 3 separate patches applied to it, necessary for my video card driver and two proprietary applications I had. Two of them had conflicting changes, which meant I needed a 4th patch to resolve the differences between them. Now whenever a security issue was fixed in the upstream kernel, I either had to wait for the vendors of those 3 patches to release an update to the new kernel version, which took from one to six months, or I had to manually maintain the upstream security patches until the other patch vendors caught up.

After a few years, the vendors managed to get included in the upstream kernel source, and I was able to stop the balancing act, but you can see what a mess it was in the mean time. Don't inflict that on your programmers unless you have to.

Karl Bielefeldt
  • 146,727
  • 38
  • 279
  • 479
3

No. It is not a standard technique for software development. It remains a workaround to solve an acute problem and has clear drawbacks. Violation of the Liskov Substitution Principle comes to mind. Monkey patching makes it seriously harder to reason about programs. For your own programs you should place the code where it belongs. For third party libs you will always live in the danger, that your patch won't work with the next version of the lib.

Of course monkey patching is useful if you know what you are doing and do not have the time to implement a SOLID solution. But you should never consider this a standard technique and build monkey patch upon monkey patch.

BTW, did you ever write a unit test for a monkey patch?

scarfridge
  • 1,796
  • 13
  • 20
  • I don’t think you can apply LSP here. It has a very specific definition concerning subtypes. – Konrad Rudolph Apr 18 '12 at 10:23
  • @KonradRudolph Monkey patching an object changes its type. In dynamically typed languages every type t with the same interface as type u is a subtype of u. If it walks like a duck... – scarfridge Apr 18 '12 at 16:38
  • “… changes its type” – fair enough. Makes sense. – Konrad Rudolph Apr 18 '12 at 16:45
  • RE "It is not a standard technique for software development.", it seems to be done *all the time and in major libraries" in Python for testing. – Tommy Jan 24 '17 at 16:42