2014-10-18 14 views
0

Моя цель - реализовать оператор сложения для математического вектора. Мне нужна возможность добавлять скаляры, массивы в MyVector. Также мне нужно, чтобы операция была коммутативной, поэтому я могу добавить числа в MyVector и MyVector к числу. Я воспользовался рецептом здесь In Ruby, how does coerce() actually work? и несколькими другими интернет-ресурсами, чтобы определить следующий оператор +.метод ruby ​​coerce не называется как ожидалось

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, который терпит неудачу. Мой вопрос: почему метод coerce для MyVector не вызван?

ответ

1

coerce делает принуждения для числовых типов. Номер Array не является числовым. Array#+ не является дополнением, оно является конкатенацией, оно ведет себя иначе, чем цифровое добавление, например. [1, 2, 3] + [4, 5, 6] - это не то же самое, что и [4, 5, 6] + [1, 2, 3].

+0

Есть ли способ для выполнения коммутирующего массива с MyVector? Можно расширить определение для Array # +, возможно? – Vineet

1

Кажется, что принуждение Ruby работает только с Fixnum, поэтому Array не поддерживается в вашем случае. Сообщение об ошибке «Неявное преобразование MyVector в массив (TypeError)», которое вы видели, было создано с помощью встроенного метода Ruby Array +.