Tell me more ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In the book I am reading from currently, it says that monkeypatching is, to cut it short, a Bad Thing. Its example for monkeypatching is basically:

class Fixnum
  def print_out
    puts "foo"
  end
end

After the example, it warns that this is considered a bad practice. Later in the book, it introduces class_eval(), which can do the same thing. Is class_eval() bad practice?

share|improve this question
Is the term "monkeypatching" unique to Ruby? I've never heard it before, though I have dabbled a bit in Ruby a few times. Could you explain what it is, and what class_eval() does differently? – FrustratedWithFormsDesigner Apr 30 '12 at 20:24
Monkeypatching is adding bits and pieces of functionality to an already existing class. – Joe Loo Apr 30 '12 at 20:25
Is there a specific situation where this is preferable or better to using inheritance? And if class_eval() also lets you monkeypatch a class, I'm guessing the "monkeypatch" is the sole paramter to this function? Maybe using class_eval() avoids security issues? – FrustratedWithFormsDesigner Apr 30 '12 at 20:26
1  
I think this: ruby.11.n6.nabble.com/… explains the difference. – FrustratedWithFormsDesigner Apr 30 '12 at 21:52

closed as not constructive by Jarrod Roberson, Robert Harvey, FrustratedWithFormsDesigner, gnat, Walter May 1 '12 at 11:26

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or specific expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, see the FAQ for guidance.

2 Answers

For the uninitiated, monkeypatching is what you're doing when you add to or alter an existing class. In ruby, you can do things like this:

class C
    def func1
        # ...
    end
end

class C
    def func1
        # ...
    end
    def func2
        # ...
    emd
end

The second "definition" of C lets you define new methods or re-define existing ones. The two need not be in the same source file.

I see "monkeypatching" is "enhancing the implementation of an external class without modifying the supplied source".

If for some reason the functionality provided by some external class or module isn't sufficient for my needs, I need to update or fix it. Sometimes subclassing is an option, but not if you're not the one calling new. In these cases you can modify the existing gem/module, but this could quickly turn into a gem management nightmare. Monkeypatching provides a much more manageable alternative. It has served me well so far.

The key thing to remember when monkeypatching is, are you altering the behavior of a module in a way that could affect other code? If you are just adding methods that don't override methods in base classes (or "created" via method_missing), then only need to worry about the possibility of that method name later being annxed by the module owner. But if you are changing/overriding existing methods, be very careful what you are doing.

And yes, class_eval is essentially the same as wrapping your code in class C and end lines, so it is effectively as "bad" as monkeypatching.

share|improve this answer

A language isn't dynamic if it can't dynamically change the program. Therefore that morally ought to include changing the classes it creates. (Morally, it also ought to be possible to change what class an object is an instance of. That scares a lot of folks though.) You've just got a way to do those changes in Ruby.

Of course, it's a sharp tool that you can do great damage with, but it lets you do some really neat things with minimal code. It comes from a philosophy that says that languages should enable, not restrict. Still, it's usually best to not use it for everything or you'll get a headache from trying to figure out what's going on…

share|improve this answer

Not the answer you're looking for? Browse other questions tagged or ask your own question.