views:

89

answers:

2

Let's say your coworker monkeypatches the Fixnum class and redefines the + method to subtract instead of add:

class Fixnum
  def +(x)
    self - x
  end
end

>> 5 + 3
=> 2

Your problem is you want to access the original functionality of the + method. So you drop this code in before his in the same source file. It aliases the + method to "original_plus" before he monkeypatches it.

class Fixnum
  alias_method :original_plus, :+
end

class Fixnum
  def +(x)
    self - x
  end
end

Now you can access the original functionality of the + method through original_plus

>> 5 + 3
=> 2
>> 5.original_plus(3)
=> 8

But what I need to know is this:

Is there any other way of loading this alias BEFORE his monkeypatch loads besides sticking it into the same source file that he modified?

There are two reasons for my question:

  1. I may not want him to know that I have done this
  2. If the source file is altered so that the alias ends up BELOW the monkeypatch, then the alias will no longer produce the desired result.
+5  A: 

Sure. Just stick the anti-monkeypatch in your code before you require his source file.

 % cat monkeypatch.rb
 class Fixnum
   def +(x)
     self - x
   end
 end
 % cat mycode.rb
 class Fixnum
   alias_method :original_plus, :+
 end
 require 'monkeypatch'
 puts 5 + 3 #=> 2
 puts 5.original_plus(3) #=> 8
rampion
+2  A: 

Monkeypatching is nice to extend an existing class and add new features. Monkeypatching to change the behavior of existing features is just crazy!

Seriously, you should talk with your coworker.

If like in your example, he did redefine an existing method just to change its behavior, you should talk to him and advise him to use alias_method_chain in order to save the existing behavior.

Vincent Robert
Not familiar with that. Is that a Rails method? (I'm only concerned with Ruby here.)
pez_dispenser
alias_method_chain seems to be a synonym for alias_method (from what I can tell). So, in that sense, yes, I agree with you, he should have left the + method alone and instead aliased it as coworker_plus. That way I could have accessed the original. But we don't always have control over what our coworkers do, do we? Sometimes they happen to be more politically influential and domineering, let's say (for example).
pez_dispenser