What is Monkey patch?

Asked

Viewed 1,855 times

19

What is Monkey patch in programming and what is the usefulness and risk of using such a technique?

This concept varies from technology to technology, from language to language or what?

And another question: why is that name so weird?

  • I loved the etymology of the word according to Wikipedia: https://en.m.wikipedia.org/wiki/Monkey_patch

  • 2

    Link to read: http://blog.locaweb.com.br/artigos/development-artigos/monkey-patch-sim-nao-quando/

2 answers

15


What is Monkey patching?

The term, which has a strange name, refers to when you modify or extend the behavior of an application at its runtime. The term popular form is called Monkey patching, but technically Dynamic Runtime patching.

The term was already known, but the Google Trends shows that it has become popular with Ruby, a 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!

Note that class behavior String was changed at runtime as I was able to override a class method.

Why is it dangerous?

Yes... it can be very dangerous.

Ruby, like Python, has the premise that the programmer knows what he’s doing, so things like this are more accessible. In languages like Java and C#, the process gets a little more restricted. Some say it is a protection against the biggest threat of an application: the developer.

But yes, Monkey patching can be dangerous as in this case of String. There are some uses, as already mentioned in other answers, to use as a workaround of some bug or strange behavior in applications, but that can, if poorly executed, major complications.

The Wikipedia brings some legal information about the ups and downs of the patching Monkey. If it is poorly documented, it can cause problems:

  1. It can cause authentification divergences when the object that was "monkeypatched" assumes things about the original object that are not necessarily true after the updates. This can break the Monkey patching, and consequently the application.
  2. If two parts of the application try to make Monkey patch on the same object, the last one that runs will be the winner of the race. This can cause confusion.
  3. It can cause divergences between the original code and the actual behavior, if the programmer you are reading does not know about the patch.

But... Monkey patching can be useful too.

Plato said:

There is nothing good or bad but these two things: wisdom which is good and ignorance which is evil.

Almost everything has a good part.

And as much as there are those who don’t like it, Monkey patching can be quite useful for those who write automated tests. A small Ruby example of a test:

# ./user_service.rb
module UserService
  extend self

  BASE_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 making Monkey patching in the HTTP class, it is possible to create a mock for the tests.

Adoption

C# has something like "Monkey patching" through Extension Methods, which does not allow modifying but adding behavior. It is safe and developer friendly. It is not well Monkey patching because it does not let you change behavior, but rather extend, and at the compilation level.

In other languages that do not have such clear support for runtime extension or modification, there is metaprogramming and reflection, which can give some kind of flexibility in this sense.

Python, for example, like Ruby, gives great flexibility to Monkey patching, since classes are mutable and methods are mere attributes. See the Python example:

class Pessoa:
    def falar_oi():
        return "Oi!"

Pessoa.falar_oi()
# => "Oi"

Pessoa.falar_oi = lambda: "Não quero!"

Pessoa.falar_oi()
# => "Não quero!"

Why is it called so?

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 the hidden behavior, in a sneaky way. Turned Monkey for 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]

6

It is a gambit that allows you to modify an application when it is running or outside of its normal context. It is needed to fix problems or modify behavior that the application does not allow.

It is possible to modify fonts when you have to solve a bug.

When the software updates you will lose this patch.

In systems like Protheus for example, you do this a lot, without touching it out of the ordinary you can’t use it. Every modification they send you has a new problem and you have to fix it.

  • 1

    I didn’t know those patches in Protheus used to give so much trouble

  • 2

    Hi Jefferson, it’s all day every day doing this, it’s sad.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.