Is Monkey Patching (or Duck Punching) Still A Viable Solution?

If a third-party JavaScript library requires a modification, does it make sense to Monkey Patch or Duck Punch it?

Written by Jonathan "JD" Danylko • Last Updated: • Develop •
The Three Monkeys

You found this great JavaScript library and you think, "this is going to be awesome."

You run your package installer and find out it doesn't have a certain piece of functionality you need, but it has 95% of everything else.

What do you do?

It would make sense to fork it and run with a customized version of the library. You think to yourself, "I only need to modify a small piece of code to make it work."

However, if a new version of the JavaScript library comes out, you have to integrate it back into the library with all of your changes.

This makes it kind of a pain in the rump.

There are two ways to fix this situation.

Monkey Patch (or Duck Punching)

With dynamic languages all the rage lately (including JavaScript), there is a way to throw patch code at an existing library and replace their method call with your own.

This process is called Monkey Patching. I've also heard it called Duck Punching.

You are essentially creating a variable or function to mimic the same signature as another method in their code and assigning their code to use your newly updated code.

Let's use an example.

If we have a JavaScript implementation of a shopping cart and we perform calculations on the cart, we may have something like this:

<script>
    var total = cart.calculateOrder();
</script>

Let's say we want to modify this to add sales tax. We can monkey patch it.

First, you'd want to save the calculateOrder() function so we can improve on their design.

Then we replace it with a newer function.

<script>
    var oldMethodCall = cart.calculateOrder;
    cart.calculateOrder = function() {
        var total = oldMethodCall.apply(this);
        // do other stuff here to add sales tax to "total".
    }
</script>

As you can see, it provides a simple way to add additional functionality without modifying too much code (and keeps the implementation process intact as well).

...Or Find a Better Library

This brings me to my point.

I realize we've come a long way since the old days of using JavaScript. Monkey Patching was something available to developers to implement additional code without removing existing functionality.

Now? If the library is worth it's salt, it'll have the proper hooks to make your development easier.

For example, one issue I have with Twitter's Bootstrap is the Dropdowns don't change when selected. I understand it's a Url link, but I want the selected link to show up in the dropdown box.

This dropdown component wasn't made to do this.

So how do we fix it?

At first glance, there are events attached to the dropdown that aren't what we're looking for to select an item.

We could go through the source code and see how they pick the item and monkey patch it?

If we look at the dropdown events, we find out that there isn't a click event...or is there?

After digging around, I found out that the dropdown does have a click event called "click.bs.dropdown".

So instead of Monkey Patching, we actually have a legitimate API to work with when someone selects the item.

Our code would look like this:

$(".dropdown").on("click.bs.dropdown", function(e) {
    if (e && e.target) {
        var ul = $(e.target).closest("ul");
        if (ul.hasClass("dropdown-menu")) {
            $("#dropdownMenu1").html($(e.target).html() + "<span class=\"caret\"></span>");
        }
    }
});

The good news is that we don't have to implement any monkey patching. We simply access the event API and add our code for additional functionality.

This provides the 5% functionality we were looking for in a dropdown because it was written with events in mind from the get-go.

Conclusion

With the amount of JavaScript projects modified daily (yes, daily), most of the hooks into an authors' JavaScript library are becoming more standard allowing developers to access these hooks, making developers happier in their web careers.

As you can see, the API of a library is paramount when it comes to satisfying developers.

Therefore, no monkeys (or ducks) were harmed in the writing of this JavaScript.

Was there a JavaScript library that didn't contain a proper API? Did you replace it with something else?

Post your comments below.

ASP.NET 8 Best Practices on Amazon

ASP.NET 8 Best Practices by Jonathan Danylko


Reviewed as a "comprehensive guide" and a "roadmap to excellence" with over 120 Best Practices for ASP.NET Core 8, Jonathan's first book by Packt Publishing explores proven techniques for every phase of the SDLC.

Learn industry-standard concepts to improve your coding, debugging, and deployment of ASP.NET Core websites.

Order now on Amazon.com button

Picture of Jonathan "JD" Danylko

Jonathan "JD" Danylko is an author, web architect, and entrepreneur who's been programming for over 30 years. He's developed websites for small, medium, and Fortune 500 companies since 1996.

He currently works at Insight Enterprises as an Architect.

When asked what he likes to do in his spare time, he replies, "I like to write and I like to code. I also like to write about code."

comments powered by Disqus