|# Suppose DogBehavior and Dog are defined in a gem.|
|puts "i am now peeing"|
|# Here is the result of running the interface as-is.|
|# => 'i am now peeing'|
|# Now say we want to alter the behavior of Dog#go_pee. We could monkey patch|
|# DogBehavior by copying the method definition, but we set ourselves up for|
|# getting out-of-sync with the original. If such an upstream change were to|
|# result in bugs, then tracking those down can be tough if you forget that|
|# it's been monkey patched.|
|# Here is a different way that doesn't alter the original method definition.|
|puts 'first go outside'|
|puts 'then i go back inside'|
|# Now monkey patch the class to include the altered behavior.|
|# => first go outside|
|# => i am now peeing|
|# => then i go back inside|
|# This makes a couple of assumptions:|
|# 1. inclusion of DogBehavior happens *before* DogBehaviorPatch|
|# 2. there are no other classes or modules re-defining #go_pee in the|
|# inheritance hierarchy between DogBehavior and DogBehaviorPatch.|
|# If those two assumptions hold, then patching behavior this way is more|
|# stable than a direct monkey patch.|
class RobotDog include DogBehavior include RobotBrain end
We really should patch
Note that each monkey-patched method takes some args, and returns a value. No side effects, afaik. So all the monkey-patch is doing is taking the same args, and returning a slightly different value. But you're right in that it can't be "obviously done" because there is a lot of logic within the original methods that needs to be repeated in the monkey-patch in order to get the desired result.
In general, the more code that your monkey patch has to copy in order to work correctly, the more likely you are setting yourself up for errors when the original implementation changes.
I've been burned by this before, and so I was just thinking about ways to avoid it in the future.
I also tossed around the idea of creating a
Re: your 2nd point, it would be annoying to have to sniff out everywhere the patch was required, and explicitly apply it. If you missed one, and if you missed one, that would be confusing. However, it would force you to be more explicit about monkey patching. Maybe making it a little painful isn't a bad thing?