dreamedge.net

coerceの活用した演算子メソッドの実装

2009-01-01T08:44:00+0000

自作のクラスに実数との加減算や乗算を定義したい場合,

baka + 9
baka * 9

といったように後ろに数値が来る場合は,演算子メソッド(def +(i)とか)を定義すればいいので簡単.

9 + baka
9 * baka

のように前に数値が来る場合に,いちいちFixnumクラスやらBignumクラスやらFloatクラスやらの演算子をオーバーライドするのは面倒.(かつ”stack level too deep”エラーを出しやすくなるのも困る)

そんな場合はcoerceを使って,IntegerやFloatクラスに型変換できるようにすればよい.
ここに詳しい解説がある.

class MyNumber
  def coerce(other)
    if Integer === other then
      [other,@value]
    else
      [Float(other),Float(@value)]
    end
  end
end
p 9 * MyNumber.new(9)  #81
p 0.9 * MyNumber.new(9) #8.1

ちなみにFixnumクラスの乗算演算子をオーバーライドする場合は以下のようにする.
なんというか,見るからに筋が悪いプログラム.

class Fixnum
  alias_method :old_product, :*
  def *(other)
    if other.class == MyNumber
      other * self
    else
      old_product(other)
    end
  end
end
p 9 * MyNumber.new(9)  #81