Ruby, like many other languages, can test for equality. Like it’s contemporaries, the language’s equality operation returns true if two things are equal and false if not. For instance, when testing two real numbers in Ruby, equality acts as you’d expect
and works appropriately for other types as well.
This is just fine for numbers, until you have to fight round-off:
Because we’re dealing with arbitrary numeric precision in Ruby, there really isn’t a “close-enough” option. Instead we have to define it ourselves.
Before we jump into that however, let’s consider Ruby’s pattern matching facilities.
Ruby defines pattern matching using an equal-tilde (
=~) to match regular expressions against strings - the return value is the offset into the string of the start of the match, or nil if the string did not contain the pattern.
Regular expressions are baked right into Ruby as part of the language, giving you direct access to matching.
=~ was not chosen for matching patterns indiscriminately.
In mathematics, the tilde combined with equals typically means congruent or approximately equal to.
The expression on the left numerically matches the expression on the right, within some tolerance.
Well, since the
=~ isn’t being used for Numerics in Ruby, there’s no reason we can’t make it do double duty.
We can define a little code that will do our approximate numerical matching for us.
Defining the operations on Numeric mean that any number will have the ability to do close matching as well as precise equality.
The precision of the tests can be set by adjusting the epsilon value in Numeric, or specifying it directly when calling the approximately_equals method
Yes, it is truly wonderful that Ruby gives you the ability to roll your own meanings to operations. Letting you deal with issues such as these really gets you past some gritty code issues with elegance.