Monkey patch
A monkey patch is a way for a program to extend or modify supporting system software locally (affecting only the running instance of the program).
Etymology
The term monkey patch seems to have come from an earlier term, guerrilla patch, which referred to changing code sneakily – and possibly incompatibly with other such patches – at runtime.[1] The word guerrilla, homophonous with gorilla (or nearly so), became monkey, possibly to make the patch sound less intimidating.[1] An alternative etymology is that it refers to “monkeying about” with the code (messing with it).
The definition of the term varies depending upon the community using it. In Ruby,[2] Python,[3] and many other dynamic programming languages, the term monkey patch only refers to dynamic modifications of a class or module at runtime, motivated by the intent to patch existing third-party code as a workaround to a bug or feature which does not act as desired. Other forms of modifying classes at runtime have different names, based on their different intents. For example, in Zope and Plone, security patches are often delivered using dynamic class modification, but they are called hot fixes.
Applications
Monkey patching is used to:
- Replace methods / attributes / functions at runtime, e.g. to stub out a function during testing;
- Modify/extend behaviour of a third-party product without maintaining a private copy of the source code;
- Apply a patch at runtime to the objects in memory, instead of the source code on disk;
- Distribute security or behavioural fixes that live alongside the original source code (an example of this would be distributing the fix as a plugin for the Ruby on Rails platform).
Pitfalls
Carelessly written or poorly documented monkey patches can lead to problems:
- They can lead to upgrade problems when the patch makes assumptions about the patched object that are no longer true; if the product you have changed changes with a new release it may very well break your patch. For this reason monkey patches are often made conditional, and only applied if appropriate.[4]
- If two modules attempt to monkey patch the same method, one of them (whichever one runs last) "wins" and the other patch has no effect, unless monkey patches are written with a pattern like
alias_method_chain
.[5] - They create a discrepancy between the original source code on disk and the observed behaviour that can be very confusing to anyone unaware of the patches' existence.
Quotes
- If it walks like a duck and talks like a duck, it’s a duck, right? So if this duck is not giving you the noise that you want, you’ve got to just punch that duck until it returns what you expect. -Patrick Ewing on Monkey/Duck patching in RailsConf 2007.[6]
Examples
The following Python example monkey patches the value of Pi from the standard math library.
>>> import math
>>> math.pi
3.141592653589793
>>> math.pi = 3
>>> math.pi
3
>>> ================================ RESTART ================================
>>> import math
>>> math.pi
3.141592653589793
>>>
See also
- Aspect-oriented programming
- Self-modifying code
- Extension method in C#
- Category in Objective-C
References
- 1 2 Limi, Alexander; Shane Hathaway (2005-12-23). "Monkey patch". Plone Foundation. Retrieved 2008-07-03.
- ↑ "Refining Ruby". 2013-02-27.
- ↑ Biswal, Bimal. "Monkey Patching in Python". Software Technology Tips. Mindfire Solutions. Retrieved 9 December 2013.
- ↑ "Maintainable JavaScript: Don't modify objects you don't own". 2010-03-02.
- ↑ "New in Rails: Module#alias_method_chain". 2006-04-26.
- ↑ "RailsConf 2007 | the Ruby on Rails Podcast". 2012-01-14. Archived from the original on January 14, 2012. Retrieved 2016-06-07.