Ruby’s open classes are great for adding behavior to existing objects. Though it’s a language feature, there to be used, I’d argue that the majority of times it is used, Open classes weren’t the most appropriate tool.
First of all, you may be setting yourself (and other developers) up for confusion. Not knowing where methods come from or why a method behaves oddly can be a problem. In the majority of cases, I find you’ve got an instance of some object, and you just want to add behavior to it.
In these cases, opening up a class and adding behavior to all instances –past, present, and future– is a bit over-kill. It’d be more appropriate to add behavior to just that instance.
If you’re intention is to make
Strings greppable, opening up the
String class might look appealing
I’m aware that
Enumerable already provides this functionality. It’s just an example.
The same thing can be accomplished with a module.
The main benefits here are that a) the addition of behavior is made explicit and b) you only change the one instance you’re working with rather than affecting every
String throughout the entire system.
One interesting implication of learning this is realizing that using
extend inside a class definition, though conceptually different, is technically identical to the above.
De-sugared, this is actually
MyClass.extend(MyModule) which is analogous to
my_string.extend(Grep). The former adds methods from
MyClass just as the latter adds
Greps methods onto
At its core, ruby is a very simple language. It takes core Object-oriented concepts (like “extending” some object) and abides by them at each layer of the abstraction stack.
This allows a little bit of knowledge about the internals of the language to pay substantial dividends in actual implementations.