Jump to content

Monkey patch: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Add link; "such as" doesn't need "etc."; add Lisp
Tags: Mobile edit Mobile web edit Advanced mobile edit
 
(46 intermediate revisions by 27 users not shown)
Line 1: Line 1:
{{Short description|Computer programming technique}}
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).
In [[computer programming]], '''monkey patching''' is a technique used to dynamically update the behavior of a piece of code at run-time. It is used to extend or modify the runtime code of [[dynamic programming language|dynamic language]]s such as [[Smalltalk]], [[JavaScript]], [[Objective-C]], [[Ruby_(programming_language)|Ruby]], [[Perl]], [[Python_(programming_language)|Python]], [[Apache_Groovy|Groovy]], and [[Lisp (programming language)|Lisp]] without altering the original source code.


==Etymology==
==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.<ref name="plone">{{cite web|url=http://plone.org/documentation/glossary/monkeypatch |title=Monkey patch |last=Limi |first=Alexander |author2=Shane Hathaway |date=2005-12-23 |publisher=Plone Foundation |accessdate=2008-07-03 |url-status=bot: unknown |archiveurl=https://web.archive.org/web/20080604220320/http://plone.org/documentation/glossary/monkeypatch |archivedate=2008-06-04 }}</ref> The word ''[[guerrilla]]'', homophonous with ''[[gorilla]]'' (or nearly so), became ''monkey'', possibly to make the patch sound less intimidating.<ref name=plone /> An alternative etymology is that it refers to “monkeying about” with the code (messing with it).
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. The word ''[[guerrilla]]'', nearly homophonous with ''[[gorilla]]'', became ''monkey'', possibly to make the patch sound less intimidating.<ref name="plone">
{{cite web
| url=https://docs.plone.org/appendices/glossary.html#term-Monkey-patch
| url-status=live
| title=Glossary — Definition of 'Monkey patch'
| website=[[Plone_(software) | Plone Content Management System]]
| archive-url=https://web.archive.org/web/20210122092034/https://docs.plone.org/appendices/glossary.html#term-Monkey-patch
| archive-date=2021-01-22
| access-date=2021-07-02
| quote=when someone created a guerrilla patch very carefully and tried to avoid any battles, they tried to make it sound less forceful by calling it a monkey patch
}}
</ref>

An alternative etymology is that it refers to “monkeying about” with the code (messing with it).{{cn|date=January 2024}}

Despite the name's suggestion, the "monkey patch" is sometimes the official method of extending a program. For example, web browsers such as [[Firefox]] and [[Internet Explorer]] used to encourage this, although modern browsers (including Firefox) now have an official extensions system.{{cn|date=January 2024}}


==Definitions==
==Definitions==
The definition of the term varies depending upon the community using it. In [[Ruby (programming language)|Ruby]],<ref>{{cite web|url=http://blog.headius.com/2012/11/refining-ruby.html|title=Refining Ruby|date=2013-02-27}}</ref> [[Python (programming language)|Python]],<ref>{{cite web|last=Biswal|first=Bimal|title=Monkey Patching in Python|url=http://www.mindfiresolutions.com/Monkey-Patching-in-Python-1238.php|work=Software Technology Tips|publisher=Mindfire Solutions|accessdate=9 December 2013}} </ref> and many other [[dynamic programming language]]s, 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 (software)|Plone]], security patches are often delivered using dynamic class modification, but they are called ''hot fixes''.{{Citation needed|date=June 2009}}
The definition of the term varies depending upon the community using it. In [[Ruby (programming language)|Ruby]],<ref>{{cite web |last1=Nutter |first1=Charles Oliver |title=Refining Ruby |url=http://blog.headius.com/2012/11/refining-ruby.html |website=Charles Oliver Nutter}}</ref> [[Python (programming language)|Python]],<ref>{{cite web |last=Biswal |first=Bimal |title=Monkey Patching in Python |url=http://www.mindfiresolutions.com/Monkey-Patching-in-Python-1238.php |url-status=dead |accessdate=9 December 2013 |work=Software Technology Tips |publisher=Mindfire Solutions |archive-date=22 August 2012 |archive-url=https://web.archive.org/web/20120822051047/http://www.mindfiresolutions.com/Monkey-Patching-in-Python-1238.php }}</ref> and many other [[dynamic programming language]]s, 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 (software)|Plone]], security patches are often delivered using dynamic class modification, but they are called ''hot fixes''.{{Citation needed|date=June 2009}}


==Applications==
==Applications==
{{Unreferenced section|date=January 2024}}
Monkey patching is used to:
Monkey patching is used to:
*Replace [[Method (computer science)|methods]] / [[Classes (computer science) |classes]] / [[Attribute (computing)|attributes]] / [[subroutine|functions]] at runtime, e.g. to [[method stub|stub]] out a function during testing;
*Replace [[Method (computer science)|methods]] / [[Classes (computer science) |classes]] / [[Attribute (computing)|attributes]] / [[subroutine|functions]] at runtime, e.g. to [[method stub|stub]] out a function during testing;
Line 13: Line 30:
*Apply the result of a patch at runtime to the state in [[memory (computing)|memory]], instead of the source code on [[Disk storage|disk]];
*Apply the result of a patch at runtime to the state in [[memory (computing)|memory]], instead of the source code on [[Disk storage|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);
*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);
*Explore different automated fixes to provide self-healing.<ref>{{Cite journal|last=Durieux|first=Thomas|last2=Hamadi|first2=Youssef|last3=Monperrus|first3=Martin|date=2020|title=Fully Automated HTML and JavaScript Rewriting for Constructing a Self‐healing Web Proxy|journal=Software Testing, Verification and Reliability|language=en|volume=30|issue=2|doi=10.1002/stvr.1731|issn=0960-0833|arxiv=1803.08725}}</ref>


==Pitfalls==
==Pitfalls==
Carelessly written or poorly documented monkey patches can lead to problems:
Malicious, incompetently written, and/or poorly documented monkey patches can lead to problems:

*They can lead to upgrade problems when the patch makes assumptions about the patched [[object (computer science)|object]] that are no longer true; a new release may very well break the patch. For this reason monkey patches are often made conditional, and only applied if appropriate.<ref>{{cite web|url=http://www.nczonline.net/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/|title=Maintainable JavaScript: Don't modify objects you don't own|date=2010-03-02}}</ref>
*If two modules attempt to monkey patch the same [[Method (computer science)|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 <code>alias_method_chain</code>.<ref>{{cite web|url=http://weblog.rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain|title=New in Rails: Module#alias_method_chain|date=2006-04-26}}</ref>
*They can lead to upgrade problems when the patch makes assumptions about the patched [[object (computer science)|object]] that are no longer true; a new release may very well break the patch. For this reason monkey patches are often made conditional, and only applied if appropriate.<ref>{{cite web |last1=Zakas |first1=Nicholas C. |title=Maintainable JavaScript: Don't modify objects you don't own - Human Who Codes |url=https://humanwhocodes.com/blog/2010/03/02/maintainable-javascript-dont-modify-objects-you-down-own/ |website=Human Who Codes |language=en |date=2 March 2010}}</ref>
*If two modules attempt to monkey patch the same [[Method (computer science)|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 <code>alias_method_chain</code>.<ref>{{cite web |title=New in Rails: Module#alias_method_chain |url=https://rubyonrails.org/2006/4/26/new-in-rails-module-alias_method_chain |website=Ruby on Rails |language=en}}</ref>
*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.
*They create a discrepancy between the original source code and the observed behaviour that can be very confusing to anyone unaware of the existence of the patch. For example, the [[Linux]] kernel detects proprietary and other third-party modules such as the [[Nvidia]] driver, which tamper with kernel structures, so that developers will not waste their time trying to debug a problem that they cannot fix.<ref>{{Cite web|title=Tainted kernels — The Linux Kernel documentation|url=https://www.kernel.org/doc/html/v4.15/admin-guide/tainted-kernels.html|access-date=2020-07-12|website=www.kernel.org}}</ref>
*They can be written with malicious code in order to attack the main program, or each other. As an example, in 2009, Giorgio Maone, developer of [[NoScript]], attacked the [[Adblock Plus]] extension for Firefox, adding exceptions so that advertisements on his own websites would work. The offending code also made sure that if the user attempted to remove the exceptions, they would be added again. The spat caused widespread anger, leading to a back and forth war between new adblock rules being pushed to users, followed by Maone sabotaging the new ones, which eventually led to Mozilla stepping in to change policies regarding add-ons.<ref>{{Cite web|last=Paul|first=Ryan|date=2009-05-04|title=Mozilla ponders policy change after Firefox extension battle|url=https://arstechnica.com/information-technology/2009/05/mozilla-ponders-policy-change-after-firefox-extension-battle/|access-date=2020-07-12|website=Ars Technica|language=en-us}}</ref>


== Examples ==
== Examples ==
The following Python example monkey-patches the value of [[Pi]] from the standard math library to make it compliant with the [[Indiana Pi Bill|laws]] of the great [[United States|American]] State of [[Indiana Pi Bill|Indiana]].
The following Python example monkey-patches the value of [[Pi]] from the standard Python math library to make it compliant with the [[Indiana Pi Bill]].
<syntaxhighlight lang="pycon">
<syntaxhighlight lang="pycon">
>>> import math
>>> import math
>>> math.pi
>>> math.pi
3.141592653589793
3.141592653589793
>>> math.pi = 3.2 # monkey patch the value of PI in the math module
>>> math.pi = 3.2 # monkey-patch the value of Pi in the math module
>>> math.pi
>>> math.pi
3.2
3.2
Line 39: Line 57:
==See also==
==See also==
{{Wikiquote}}
{{Wikiquote}}
* [[Polyfill (programming)|Polyfill]]
* [[Advice (programming)]]
* [[Aspect-oriented programming]]
* [[Aspect-oriented programming]]
* [[Self-modifying code]]
* [[Extension method]] in C#
* [[Objective-C#Categories|Category]] in Objective-C
* [[Objective-C#Categories|Category]] in Objective-C
* [[Dynamic loading]]
* [[Dynamic loading]]
* [[Extension method]] in C#
* [[Self-modifying code]]


==References==
==References==

Latest revision as of 14:02, 30 March 2024

In computer programming, monkey patching is a technique used to dynamically update the behavior of a piece of code at run-time. It is used to extend or modify the runtime code of dynamic languages such as Smalltalk, JavaScript, Objective-C, Ruby, Perl, Python, Groovy, and Lisp without altering the original source code.

Etymology

[edit]

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. The word guerrilla, nearly homophonous with gorilla, 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).[citation needed]

Despite the name's suggestion, the "monkey patch" is sometimes the official method of extending a program. For example, web browsers such as Firefox and Internet Explorer used to encourage this, although modern browsers (including Firefox) now have an official extensions system.[citation needed]

Definitions

[edit]

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.[citation needed]

Applications

[edit]

Monkey patching is used to:

  • Replace methods / classes / 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 the result of a patch at runtime to the state 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

[edit]

Malicious, incompetently written, and/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; a new release may very well break the 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 and the observed behaviour that can be very confusing to anyone unaware of the existence of the patch. For example, the Linux kernel detects proprietary and other third-party modules such as the Nvidia driver, which tamper with kernel structures, so that developers will not waste their time trying to debug a problem that they cannot fix.[6]
  • They can be written with malicious code in order to attack the main program, or each other. As an example, in 2009, Giorgio Maone, developer of NoScript, attacked the Adblock Plus extension for Firefox, adding exceptions so that advertisements on his own websites would work. The offending code also made sure that if the user attempted to remove the exceptions, they would be added again. The spat caused widespread anger, leading to a back and forth war between new adblock rules being pushed to users, followed by Maone sabotaging the new ones, which eventually led to Mozilla stepping in to change policies regarding add-ons.[7]

Examples

[edit]

The following Python example monkey-patches the value of Pi from the standard Python math library to make it compliant with the Indiana Pi Bill.

>>> import math
>>> math.pi
3.141592653589793
>>> math.pi = 3.2   # monkey-patch the value of Pi in the math module
>>> math.pi
3.2
================================ RESTART ================================
>>> import math
>>> math.pi
3.141592653589793
>>>

See also

[edit]

References

[edit]
  1. ^ "Glossary — Definition of 'Monkey patch'". Plone Content Management System. Archived from the original on 2021-01-22. Retrieved 2021-07-02. when someone created a guerrilla patch very carefully and tried to avoid any battles, they tried to make it sound less forceful by calling it a monkey patch
  2. ^ Nutter, Charles Oliver. "Refining Ruby". Charles Oliver Nutter.
  3. ^ Biswal, Bimal. "Monkey Patching in Python". Software Technology Tips. Mindfire Solutions. Archived from the original on 22 August 2012. Retrieved 9 December 2013.
  4. ^ Zakas, Nicholas C. (2 March 2010). "Maintainable JavaScript: Don't modify objects you don't own - Human Who Codes". Human Who Codes.
  5. ^ "New in Rails: Module#alias_method_chain". Ruby on Rails.
  6. ^ "Tainted kernels — The Linux Kernel documentation". www.kernel.org. Retrieved 2020-07-12.
  7. ^ Paul, Ryan (2009-05-04). "Mozilla ponders policy change after Firefox extension battle". Ars Technica. Retrieved 2020-07-12.