Extending and Modifying Preexisting Code
When I introduce Ruby to new students, my first example is often meant to shake them up a little. It is relatively unremarkable, but to those who have not worked in languages with an open class system before, it can be quite alarming:
class Fixnum def +(other) 42 end end
The implications typically donât sink in until I fire up irb:
>> 2 + 2 => 42
This demonstration is typically followed by a firm ânever do thisâ reminder, but I continue to use it because it opens peopleâs eyes to just how different Ruby is from most other languages. The standard response to this example is a flurry of questions about how Rubyists manage to make heads or tails of things when people can go all willy-nilly with extending classes as they see fit. Thatâs what this section is all about.
Weâre going to talk about two related but somewhat distinct topics here. The first is extending Ruby classes with new behaviors by reopening classes; the second is actually modifying existing behaviors to fit new requirements. What separates the two is primarily the level of controversy, and hence the necessary level of care.
Because adding new functionality is the less dangerous of the two, weâll start with that and go over some of the specifics.
Adding New Functionality
In Chapter 1, Driving Code Through Tests, I mentioned
and made use of a small extension to Test::Unit
that dynamically defines test methods for us. As previously mentioned, weâve borrowed this functionality ...
Get Ruby Best Practices now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.