Is a bad practice to monkey patch a base ruby class?

monkeypatching, ruby

Solution

Monkey patching isn't considered to be a bad practice unless you are writing odd methods that do not have PatchedClass-related behavior (for example, `String.monkeyPatchForMakingJpegFromString` is rather bad, but `Jpeg.fromString` is good enough.)

But if your project is rather large, the libraries that you use in it may happen to have colliding patches, so you may have one more problem with all these patching stuffs. In Ruby 2.0, refinements come to an aid. They work as follows: you define a `module`, `refine` your (even core) class in it, and then use that module where it's necessary. So, in your code it works as:

YourClass.new.refinedMethodFromCoreClass #=> some result

But

CoreClass.refinedMethodFromCoreClass

produces `undefined method` exception.

That's all monkey patching stuff: monkey patching is useful and convenient, but refinements add some features, that make your code more secure, maintainable and neat.

Problem

I'm working on a ruby project in which we are planning to do some operations with ruby strings. Some operations are simple (like counting the number of words) and others more complex (like checking if a given string is in the correct language). A possible way to implement this is by patching the `String` class with extra methods, without modifying any existing methods, and adding behaviors like `"some string".word_count` and `"some string".cjk?`. Another approach, based on `FileUtils` is to create a class or module full of methods and always use string as parameters, like `OddClassName.word_count("some string")` and `OddClassName.cjk?("some string")`. We like the first better because of readability. I understand that monkey patching a basic class as described in the first alternative can have name clashes. However, if this is the main application, not a library, should I worry with it at all? So, the questions are: - Is adding methods to ruby base classes a bad practice? If yes, is that in all cases or only in some cases? - What is the best approach to accomplish this? - What could be the name of 'OddClassName'? Please suggest any alternatives.

Original source