5.16. Coercing Numeric Values
Coercion can be thought of as another form of implicit conversion. When a method (+ for example) is passed an argument it doesn't understand, it tries to coerce the receiver and the argument to compatible types and then do the addition based on those types. The pattern for using coerce in a class you write is straightforward:
class MyNumberSystem def +(other) if other.kind_of?(MyNumberSystem) result = some_calculation_between_self_and_other MyNumberSystem.new(result) else n1, n2 = other.coerce(self) n1 + n2 end end end
The value returned by coerce is a two-element array containing its argument and its receiver converted to compatible types.
In this example, we're relying on the type of our argument to perform some kind of coercion for us. If we want to be good citizens, we also need to implement coercion in our class, allowing other types of numbers to work with us. To do this, we need to know the specific types that we can work with directly and convert to those types when appropriate. When we can't do that, we fall back on asking our parent class.
def coerce(other) if other.kind_of?(Float) return other, self.to_f elsif other.kind_of?(Integer) return other, self.to_i else super end end
Of course, for this to work, our object must implement to_i and to_f.
You can use coerce as part of the solution for implementing a Perl-like autocon-version of strings to numbers:
class String def coerce(n) if self['.'] [n, Float(self)] else [n, Integer(self)] end end end x = 1 + "23" # 24 y = 23 * "1.23" # 28.29
We don't necessarily recommend this. But we do recommend that you implement a coerce method whenever you are creating some kind of numeric class.