Search code examples
rubymatrixcoercion

Understanding coercion


I've submitted a pull request, which modifies the Matrix class so that additions can be performed with real numbers:

Matrix[ [25, 93], [-1, 66] ] + 5

The Matrix class has a method +(), which is called in this case.

I would also like users to be able to change the order of the operation to

5 + Matrix[ [25, 93], [-1, 66] ]

The Matrix class seems to support this order of operation for the *() method and I'm unsure how to implement this for the +() method.


Solution

  • Coercion is handled with coerce method. This method is to return two elements for which given operator/method is to be retried. Matrix defines coerce like:

    def coerce(other)
      case other
      when Numeric
        return Scalar.new(other), self
      else
        raise TypeError, "#{self.class} can't be coerced into #{other.class}"
      end
    end
    

    Note however that it is not changing the order of the operands, but rather converts numeric value into a Scalar class. Hence, ruby seeing 5 + Matrix[...] will execute Scalar.new(5) + Matrix[...].

    Scalar class is defined within the same file and defines its own set of operators, including + and '-'. So what you need to do is get rid of line Scalar.Raise ErrOperationNotDefined, "+", @value.class, other.class and enforce your code here, for example with other + self