/ DEVELOPMENT

Monkey patching and Duck punching

aka the metaprogramming zoo

I’ve been designing and building software for years, in many different languages.  I love to explore the different abstractions and conventions as you move from language to language.  I’ve worked in Pascal, Java, Python, every flavour of MS and most recently Ruby (not to mention all the somewhat secondary languages of JavaScript and CSS).  I often refer to Ruby (and more specifically RoR), as a language that fully embraces “the magic happens here”.  It is a language entirely predicated on conventions and a deep inheritance of every object in the pipeline.  I recently stumbled across a couple of terms that gave this abstraction a name and made the process of using it overt rather than “just because”.  I like the terms monkey patching and duck punching because they force you to acknowledge what you’re doing, and then ask “Why am I doing it” and “Is this the right solution”.First, for you literalists in the group, yes I know that that is a gorilla in the picture above.  But I was actually quite tickled to find that picture because of the etymology of monkey patching in the first place:

The term monkey patch seems to have come from an earlier term, guerrilla patch, which referred to changing code sneakily at runtime. The word guerrilla, homophonous with gorilla, became monkey, possibly to make the patch sound less intimidating.The key to this statement is “change code … at runtime”.  Compiled languages, historically, allowed you to define an object (loosely, that could be struct, class, type, whatever) at design time, but fixed the representation of that object when the code was compiled.  If you wanted to change it: recompile.  Over the years though, largely through the rise of interpreted languages and the rise of OO, began introducing the concept of ‘dynamic’ and generic types (think ‘var’ and ‘object’).  In some cases this was purely compiler magic that extrapolated the type for you at compile time, and in others, it used the class hierarchy to substitute a more specific class for the generic.  This is where the concept of strongly typed versus dynamically typed came from. On the whole, though, once the signature of the object was defined, it was fixed.  Recent incarnations of .Net have gone a step further and added the ‘dynamic’ type which is a completely user defined, but runtime malleable object, largely possible due to the CLR or the quasi-interpreted nature of .net.  A new breed of languages…I call them interpreted, but that’s not always true, or even relevant….use something called ‘Duck typing’, i.e. if it walks like a duck, looks like a duck and sounds like a duck, its probably a duck.  That is, if the object looks and acts like an object of type A, then it is of type A for all intents and purposes.  Since these languages are malleable at runtime, punching can be thought of as changing the shape or behaviour of an object. Duck Punching, then, is ‘punching’ one object until it looks like a duck, and since it looks, sounds and walks like a duck, it is a duck.What we’re really talking about here is metaprogramming: writing programs that write or manipulate programs, including themselves, at runtime. If you’ve read this far, I imagine you’re thinking to yourself, “What the hell is his point?”.  Well, when you understand that you can do that, you peel off a layer of abstraction on the language itself.  Imagine taking a core object, say ActiveRecord, and deciding that each and every instance of ActiveRecord needs to log something before and after every call.  In most languages you would subclass ActiveRecord and ensure there were filters / custom calls to do that.  This would accomplish that for any class you wrote, but what about all those libraries that use ActiveRecord?  They’re not going to use your new subclass.  Well, in a language that allows you to meta-program, instead of sub-classing, you could re-write the ActiveRecord itself.  On initialization, your code could take ActiveRecord, rename the execute method to old_execute, and redefine execute to to log before and after a call to old_execute.  Then every call, even those in 3rd party libraries, would log as you wanted.It is in understanding your language, at a deep esoteric level, that gives you the power to design simple solutions to complex problems.  Insight and understanding bring you options…with a dash of creativity, you can make magic happen.

jonmholt

Jon Holt

A coach, an entrepreneur, and a no-bull advisor in growing small businesses through the use of practical strategy, light-weight governance and sitting back and thinking about running your business, regardless of what you do.

Read More