【问题标题】:ruby coerce method not called as expectedruby 强制方法未按预期调用
【发布时间】:2014-10-18 18:37:39
【问题描述】:

我的目标是为数学向量实现加法运算符。我需要向 MyVector 添加标量、数组的能力。另外我需要操作是可交换的,所以我可以将数字添加到 MyVector,并将 MyVector 添加到数字。我按照这里的配方In Ruby, how does coerce() actually work? 和其他一些互联网资源来定义以下 + 运算符。

class MyVector
    def initialize(x,y,z)
      @x, @y, @z = x, y, z
    end
    def +(other)
      case other
      when Numeric
        MyVector.new(@x + other, @y + other, @z + other)
      when Array
        MyVector.new(@x + other[0], @y + other[1], @z + other[2])
      end
    end
    def coerce(other)
      p "coercing #{other.class}"
      [self, other]
    end
end

t = MyVector.new(0, 0, 1)

p t + 1
p 1 + t

p t + [3 , 4 , 5]
p [3 , 4 , 5] + t

输出是

#<MyVector:0x007fd3f987d0a0 @x=1, @y=1, @z=2>
"coercing Fixnum"
#<MyVector:0x007fd3f987cd80 @x=1, @y=1, @z=2>
#<MyVector:0x007fd3f987cbf0 @x=3, @y=4, @z=6>
test.rb:26:in `<main>': no implicit conversion of MyVector into Array (TypeError)

显然,强制在添加数字时正在发挥作用,但似乎不适用于数组。相反,Array 类的 + 方法似乎被调用,它试图将 MyVector 转换为 Array,但失败了。我的问题是,为什么不调用 MyVector 的强制方法?

【问题讨论】:

    标签: ruby arrays operators coercion


    【解决方案1】:

    coerce 对数字类型进行强制转换。 Array 不是数字类型。 Array#+ 不是加法,它是连接,它的行为与数字加法不同,例如[1, 2, 3] + [4, 5, 6][4, 5, 6] + [1, 2, 3] 不同。

    【讨论】:

    • 有没有办法对 MyVector 执行可交换数组加法?也许有人可以扩展 Array#+ 的定义?
    【解决方案2】:

    似乎 Ruby 强制转换仅适用于Fixnum 类型,因此您的情况不支持Array。您看到的错误消息“没有将 MyVector 隐式转换为 Array (TypeError)”是由 ruby​​ Array 的内置 + 方法生成的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-16
      • 2018-08-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多