Is monkey patching mandatory with Ruby?

I like alot of the features of Ruby. Some I’m not so crazy about and its usually areas where they tried to copy Perl. One thing I’ve never been crazy about is monkey patching. It reminds me of the early days when self modifying code was frowned upon. Now it seems as though its being resurrected as the now acceptable monkey patching.

I took the following from the Discourse mailing list. (Full post here: https://meta.discourse.org/t/proposal-for-plugin-architecture-for-discourse/14501 )

Javascript and Ruby are dynamically typed languages. What you call monkey patching - being able to “reopen classes and add more functionality” - are features of those languages. And both frameworks we use on top (Rails and Ember) provide even more, extended features on top like that. Usage of them isn’t only encouraged, we even do it in the core all the time. It’s not a bug, it actually shows how awesome these languages and frameworks are: We can let everyone write plugins that extend and change every piece of the code without having to provide any explicit hooks. How awesome is that? It’s darn awesome!"

Is it now expected that if you are using Ruby that at some point you will learn and embrace monkey patching? Is that now a ruby culture imperative? I’ve always found it to produced hard-to-maintain code.

I can’t speak for the Ruby community, but in the JavaScript community, monkey patching the built-in prototypes is typically a no-no. It shouldn’t be that big of a leap to realize that we shouldn’t monkey patch our own objects either, and for the same reasons, because it’s better when an object’s behavior stays consistent. The worst is when library X and library Y both try to monkey patch the same object in incompatible ways.

Monkey patching is both very handy and very dangerous. It’s handy because, “We can let everyone … change every piece of the code.” And it’s dangerous because, “We can let everyone … change every piece of the code.”

All the effort we put in with things like scopes and namespaces and DI to make sure our code plays nicely within its own little sandbox, and monkey patching just brazenly reaches into the global environment and changes things willy nilly.

Thank you and interesting comment Jeff. Your javascript comment is relevant as the UI of Discourse is primarily Javascript and EmberJS. I did a quick Google of Javascript and monkey patching and see it is possible with extend but is interesting that it is discouraged as a normal practice.

The whole thread about let’s do the Discourse plugin architecture as a monkey patch rather than as an official plugin API amazes me. Even more amazing is that it seems to have the support of the core development team. It reminds me of phpBB plugin architecture with its self modifying code.

Monkey patching in Ruby is not mandatory, but in my opinion is more prevalent than it should be.

It’s not frowned upon nearly as much as in JavaScript and, used wisely, can even be a useful technique (e.g. for implementing a temporary, critical hotfix).

However, as it is so easy to open up a class and change it at run-time, lots of people started using it as a viable way to add add random methods to the core classes.
This is bad in my opinion and its proliferation provoked some degree of backlash: Monkeypatching is Destroying Ruby.

Nonetheless, opinion remained divided and Ruby 2.0 even shipped with refinements, an experimental feature that aims to change the way monkey patching is performed. Refinements allow developers to change built-in methods without affecting other code that uses them.

You might also find this interesting: http://blog.codinghorror.com/monkeypatching-for-humans/

Sure, adding methods to the standard objects like Object or Date is frowned upon but apart from those couple of exceptions dynamically changing objects / functions is a very core part of javascript and isn’t frowned upon at all. Being able to extend or mixin methods from different objects is a very common practice in Javascript and Ruby, it’s where a lot of the power comes from that just isn’t possible in more rigid languages like Java. I agree with the author of that quote you posted that metaprogramming is darn awesome!

You, as the author of your programs can write however you wish, you don’t have to use every feature if you don’t agree with it. That being said I’ve found learning Ruby has made me a much better programmer on the whole.

I can see people have different opinions about this, some say its useful in some cases, some say its something thats useful whenever we can fit it in to our project.

I guess for me is I am questioning whether it should be the entire plugin architecture. I understand that monkey patching offers maximum versatility but the same argument could be made for phpBB’s source code modifying plugin architecture.

Yes, I understand that you can use Ruby without monkey patching but what I am wondering if the chief reason developers reach for ruby is there love for monkey patching.

Monkey patching is useful like global variables are useful.

Code can be modified from anywhere… check.
Behavior in one part of a program varies wildly based on hard to identify operations in another part of the program… check.
Any part of the program may depend on it… check.
Two or more modules may cause a collision (that is, they may modify the same code in mutually incompatible ways)… check.

To reinforce my last point, this article has a decent list of why global variables are bad. Such as…

Non-locality – Source code is easiest to understand when the scope of its individual elements are limited.
No Access Control or Constraint Checking – A global variable can be get or set by any part of the program.
Implicit coupling.
Namespace pollution.
Testing and Confinement - source that utilizes globals is somewhat more difficult to test.

Monkey patching also suffers from all of these.