红宝石中正确的加法/乘法的存在?

时间:2009-08-16 10:28:31

标签: ruby

我已经看过如何在Ruby中重载+* my_obj + other调用my_obj.+(other).在Python中,您使用__add__执行此操作,并且对于重载__radd__有相应的other + my_obj。在Ruby中是否真的没有相应的右侧加法/乘法,这是否有必要为+的每个潜在类重新定义other

简而言之:说我有一个对象X属于我定义的一个新类。为X + 5编写代码很容易,但似乎为了处理5 + X,我需要重新定义Fixnum.+。这是真的吗?

3 个答案:

答案 0 :(得分:6)

不,您不需要重新定义Fixnum#+(或ruby的数字类的任何其他算术方法)。如果两个操作数不是同一个类,则数值类的算术方法将调用coerce。因此,如果您为类定义了一个强制方法,5 + instance_of_your_class将正常工作,而无需对Fixnum#+进行任何更改。

编辑:以下是使用强制的示例:

class MyNum
  attr_accessor :num

  def initialize(num)
    @num = num
  end

  def +(o)
    lhs, rhs = coerce(o)
    MyNum.new(lhs.num + rhs.num)
  end

  def coerce(o)
    if o.is_a? MyNum
      [self, o]
    else
      [self, MyNum.new(o)]
    end
  end
end

MyNum.new(5)+3 #=> #<MyNum:0x87fca08 @num=8>
3+MyNum.new(5) #=> #<MyNum:0x8807980 @num=8>

答案 1 :(得分:0)

RHS是强制的,需要实现需要返回适当值的to_i方法。 to_int的Numeric类实现最终会将其作为添加过程的一部分进行调用,其中RHS涉及其他类而不是严格的数字后代。

答案 2 :(得分:-1)

是。如果你想改变5 + x上的行为,你必须在任何5上重新定义+,因为你实际上正在调用5.+(x)因为Ruby将这些操作视为mechod调用。