我的目标是为数学向量实现加法运算符。我需要能够为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的强制方法?
答案 0 :(得分:1)
似乎Ruby强制仅适用于Fixnum
类型,因此在您的情况下不支持Array
。您看到的错误消息“没有隐式转换MyVector到Array(TypeError)”是由ruby Array的内置+方法生成的。
答案 1 :(得分:1)
coerce
对数字类型进行强制。 Array
不是数字类型。 Array#+
不是加法,它是串联,它的行为与数字加法不同,例如[1, 2, 3] + [4, 5, 6]
与[4, 5, 6] + [1, 2, 3]
不同。