What is monkey patch in programming and what is the usefulness and risk of using such a technique?
Does this concept vary from technology to technology, from language to language, or from what?
And another question: why this weird name?
What is monkey patch in programming and what is the usefulness and risk of using such a technique?
Does this concept vary from technology to technology, from language to language, or from what?
And another question: why this weird name?
The term, which has a strange name, refers to when you modify or extend the behavior of an application at run time. The term in popular form is called monkey patching, but technically dynamic runtime patching .
The term was already known, but the Google Trends show that became popular with Ruby, language that allows monkey patching in a ridiculously easy way. See:
puts "vnbrs".upcase
class String
def upcase
"Você foi trollado pelo monkey patching!"
end
end
puts "vnbrs".upcase
The output:
VNBRS
Você foi trollado pelo monkey patching!
Notice that the behavior of class String
was changed at runtime, since I was able to override a class method.
Ruby,likePython,hasthepremisethattheprogrammerknowswhathe'sdoing,sothingslikethatgetmoreaccessible.InlanguageslikeJavaandC#,theprocessgetsabitmorerestricted.Therearethosewhosaythatitisaprotectionagainstthegreatestthreatofanapplication:thedeveloper.
But,monkeypatchingcanbedangerouslikeinthiscaseofString
.Therearesomeuses,asalreadyquotedinotheranswers,touseasaworkaroundofsomestrangebugorbehaviorinapplications,butwhichcan,ifpoorlyexecuted,complicationsgreater.
The Wikipedia carries some good information on the ups and downs of monkey patching. If it is poorly documented, it can cause problems:
Plato said:
There is nothing good or bad except these two things: wisdom is good and ignorance is evil.
Andevenifyoudonotlikeit,monkeypatchingcanbeveryusefulforthosewhowriteautomatedtests.AsmallexampleinRubyofatest:
#./user_service.rbmoduleUserServiceextendselfBASE_URI="https://api.brasil.gov.br/"
def fetch(username)
response = HTTP.get("#{BASE_URI}/pessoas/#{username}")
JSON.parse response
end
end
# ./user_service_spec.rb
class HTTP
def self.get(url)
'{"username":"vnbrs","name":"Vinicius Brasil"}'
end
end
describe UserService do
subject { UserService.fetch("vnbrs") }
it "returns the user" do
expect(subject.name).to eq "Vinicius Brasil"
end
end
By doing monkey patching in the HTTP class, you can create a mock for the tests.
OC # has something like "monkey patching" through the Extension Methods , which does not allow modifying but adding behavior. It is safe and user friendly for the developer. It's not really monkey patching because it does not let you change behavior, but rather extend, and build level.
In other languages that do not have such clear support for extension or modification at runtime, there is metaprogramming and reflection, which can give some kind of flexibility in that sense.
Python, for example, as well as Ruby, gives a great deal of flexibility to monkey patching, since classes are changeable and methods are mere attributes. See the example in Python:
class Pessoa:
def falar_oi():
return "Oi!"
Pessoa.falar_oi()
# => "Oi"
Pessoa.falar_oi = lambda: "Não quero!"
Pessoa.falar_oi()
# => "Não quero!"
The etymology of the term is somewhat obscure. Few sources talk about it, but it is common to hear that monkey patch comes from guerrilla patch , referring to modifying behavior sneaking in a sneaky way. It turned monkey because guerrilla has the pronunciation almost identical to gorilla .
We talked about sneaking in and altering Python code at runtime; the term Guerrilla Patching was used because sometimes dynamic patches could interfere and conflict. Conflict - > Guerrilla warfare, as the conflict was dynamic and depended on the terrain. [source]
It is a game that allows you to modify an application when it is running or outside its normal context. It is necessary to fix problems or modify behavior that the application does not allow.
It is possible to modify the fonts when one has to solve a bug.
When the software updates you will lose this patch.
In systems like Protheus, for example, if you do a lot of that, without touching it out of the ordinary you can not use it. Every modification they send you has a new problem and you have to fix it.