From: Caleb Clausen Date: 2010-05-12T00:46:55+09:00 Subject: Re: In Ruby, can the coerce() method know what operator it is th On 5/10/10, Jian Lin wrote: > In Ruby, it seems that a lot of coerce() help can be done by > > def coerce(something) > [self, something] > end > > that's is, when > > 3 + rational > > is needed, Fixnum "3" doesn't know how to handle adding a Rational, so > it asks Rational#coerce for help by calling rational.coerce(3), and this > coerce instance method will tell the caller: > > # I know how to handle rational + something, so I will return you > the following: > [self, something] > # so that now you can invoke + on me, and I will deal with Fixnum to > get an answer > > So what if most operators can use this method, but not when it is (a - > b) != (b - a) situation? Can coerce() know which operator it is, and > just handle those special cases, while just using the simple [self, > something] to handle all the other cases where (a op b) == (b op a) ? > (op is the operator). Coerce does not know the operator is being called on behalf of. Here's how Rational#coerce is actually implemented. (This is from 1.8. I think in 1.9 it was rewritten in c): def coerce(other) if other.kind_of?(Float) return other, self.to_f elsif other.kind_of?(Integer) return Rational.new!(other, 1), self else super end end Generally, you want to return an array containing (a representation of) other first and then (a representation of) self. That helps ensure that when the caller calls other.op self it won't end up with the arguments backwards. So operators like - and / can work correctly. If you return self first and then other, + and * will work but, not - and /.