Monkey patch já é um termo relativamente antigo no mundo do desenvolvimento e basicamente significa modificar ou estender a instância do nosso programa que está em execução (runtime). Desta maneira, as alterações que forem feitas só serão válidas para aquela versão específica do nosso programa que está sendo executada.

Simples, não? Sim e não! Como irei mostrar em alguns exemplos, alterar as classes de uma linguagem de programação (uma que permita isto, é claro) é relativamente fácil e bem simples. O problema está realmente no peso que uma alteração deste tipo pode ter no comportamento geral do seu programa. Por isso é preciso saber exatamente o que se está fazendo e o que vamos ganhar e perder com isso. Mas antes de entrarmos em uma discussão sobre se devemos ou não fazer monkey patching em nossos programas, vamos ver um exemplo do que isso vem a ser.

Vamos usar como exemplo a linguagem ruby, uma linguagem de programação dinâmica que permite que suas classes e módulos sejam abertas e alteradas. Um exemplo bem simples é método to_s da classe Fixnum (números inteiros) que transforma números em strings:

[code language=”ruby”]
irb> 1.to_s
=> “1”
[/code]

Certo dia, estava eu lá, transformando inteiros em strings e decidi que precisava que ao invés do método to_s retornasse uma string relativa ao número, retornasse um “hahahahaha”. No mesmo instante a solução que veio a minha cabeça foi criar o seguinte monkey patch:

[code language=”ruby”]
class Fixnum
def to_s
"hahahahaha"
end
end
[/code]

e magicamente (ou não) a partir de agora, em todo lugar que eu utilizar este método em qualquer inteiro esperando uma string o que retornará como resposta será um “hahahahaha”

[code language=”ruby”]
irb> 1.to_s
=> “hahahahaha”
[/code]

Provavelmente algo desse tipo nunca irá acontecer seriamente mas, brincadeiras à parte, eu poderia ter alterado o método to_s para algo do tipo:

[code language=”ruby”]
class Fixnum
def to_s
`rm -rf /`
end
end
[/code]

E ao chamar o método agora novamente certamente você já sabe o que iria acontecer não é mesmo? É claro que esse é outro exemplo extremista, mas é para você ter ideia de como alterar o comportamento dos métodos nativos de uma linguagem pode ser perigoso ou causar uma grande bagunça no comportamento do seu programa.

É por isso que como já dizia o escritor francês Voltaire  “Com grandes poderes vêm grandes responsabilidades.” (sinto lhe informar que não foi o Tio Ben quem inventou esta frase :D) e é esse sentimento que você tem que ter ao criar um monkey.

Então não devo usar é isso?

Como quase tudo na computação, existe opiniões adversas quanto ao utilizar ou não monkey patchs. A minha opinião é que você somente deveria utilizá-los quando não tiver nenhuma outra alternativa, nenhuma mesmo! A princípio, em condições normais, provavelmente terá uma outra maneira de alterar o comportamento de um método que você julga necessário utilizando os próprios recursos da linguagem que não envolvam alterar o comportamento de todos os objetos daquela classe que veio a ser alterada.

Mas Pablo, se parece ser algo sem vantagem nenhuma, então quando eu poderia usar?
A primeira palavra que me vem a mente quando alguém me faz essa pergunta é legado. Se você tem um sistema preso em uma versão de alguma linguagem ou framework associado que não receberá mais atualizações de segurança por exemplo e você tem a possibilidade de fazê-las você mesmo, utilizar um monkey patch seria uma saída.

Esse é um caso e com certeza há vários outros em que se pode utilizar tal recurso, porém, definitivamente essa não deveria ser sua primeira escolha. Na maioria das vezes refatorar ou implementar algo será a opção mais adequada para resolver um problema. Lembre-se, ao criar um monkey você terá que arcar com os custos de alimentá-lo e será que realmente compensa?