From a semi-recent post
by Python programmer Ian Bicking:

  You can monkeypatch code in Python pretty easily, but we look down
  on it enough that we call it "monkeypatching". In Ruby they call it
  "opening a class" and think it's a cool feature.
  I will assert: we are right, they are wrong.

Today, I was frustrated by a Rails bug affecting pagination with joins. In short, it doesn’t work. At all.

Miraculously, (no, it wasn’t a coincidence—it was an actual miracle) Kevin Clark posted a message to the Rails Core list right in the middle of this episode complaining about the exact same problem. He said he was working on a fix. Jeremy Hopple responded a little over an hour later saying that he had already submitted a patch for the bug.

Visions of the nasty download/patch process started trudging through my mind, but I was desperate for a fix so I would have dealt with the ugliness. I hate hacking my local Rails (I’m running off of trunk using svn:externals) because I don’t like dealing with what happens when the change actually gets applied to trunk or dealing with merges for other changes to the same files. It’s not rocket science to get working but it’s also not fun.

Looking more closely at Jeremy’s email, he’s also distributing his patch as a Rails plugin. So:

  $ ruby script/plugin install count_limit_assocations

Now my code works. The bug is fixed. The plugin contains essentially nothing but a file that "monkey patches" some of the Rails core classes, implementing the changed version of the code.

When the change is merged into the Rails trunk, I’ll just ‘script/plugin remove’ Jeremy’s plugin.

The Rails team is already using plugins like this as a way to get new functionality into circulation as a kind of proving ground before things make it into Rails core. And as we see today, it’s also a simple, painless way to get fixes distributed before they’re reviewed and committed. Sure, you can do the more obvious thing with plugins and distribute code that implements new functionality altogether. But this "monkey patching" thing is seriously powerful and, as an end-usre in this case, I can say that it makes things better for the users of Ruby.

So Ian, with respect, no…you’re not right.

UPDATE: Ian sent me the following clarification by email (reprinted with permission—thanks Ian!):

  Hi Chad.  Saw your post on monkeypatching.  Just thought I'd clarify
  that I don't think that kind of use is wrong, and I do that frequently
  -- applying a patch at runtime to the objects in memory, instead of the
  source code on disk.  It can be expedient, and certainly a whole lot
  better than trading patches around.  The use I object to that I see in
  lots of Ruby examples (and maybe isn't indicative of most real Ruby
  code) is when people add methods to other classes that aren't meant to
  fix anything, but just because they don't have an object of their own to
  hang the method off of.  I've seen several examples where people add
  methods to Array to implement some recursive algorithm, instead of using
  a function.  Or Rails adding methods to numbers to create time delta
  objects (well, it would be good if they *were* time delta objects, but I
  understand they actually just return seconds as ints, but that's another
  issue entirely).

  The term "monkeypatch" is really meant to denote that.  It's a patch, a
  fix, an adjustment to the code.  The monkey part has a history (that
  someone left on my post) that I think more-or-less is meant to indicate
  a certain subversive intent, or at least playfully but maybe mischievous
  manipulation.  We do it often in Python, but everytime we do it we know
  we are working around the system and not with it.  Which is fine too,
  but it's not the sort of thing you want as a foundation.