2009-08-16 9 views
5

Widziałem jak przeciążenie + i * w Ruby, tak że my_obj + other rozmowy my_obj.+(other). W Pythonie, robisz to z __add__ i istnieje odpowiadający __radd__ do przeciążenia other + my_obj. Czy naprawdę nie ma odpowiednika prawostronnego dodawania/mnożenia w Ruby, i czy to powoduje konieczność przedefiniowania + dla każdej potencjalnej klasy other?Istnienie prawidłowego dodawania/mnożenia w rubinie?

W skrócie: mówię, że mam obiekt X należący do nowej klasy zdefiniowanej przeze mnie. Łatwo jest napisać kod dla X + 5, ale wydaje się, że w celu obsługi 5 + X musiałbym przedefiniować Fixnum.+. Czy to prawda?

+1

Powinienem wyjaśnić: chcę, aby 5 + X (i X + 5) zwróciło wybrany obiekt niestandardowy, a nie tylko liczbę całkowitą lub zmienną. – Peter

+0

Definicja coerce to archiwizuje. – sepp2k

Odpowiedz

6

Nie, nie trzeba zmieniać definicji Fixnum # + (ani żadnej innej arytmetycznej metody klas numerycznych ruby). Metody arytmetyczne klas numerycznych będą wywoływać coerce, jeśli dwa argumenty nie są tej samej klasy. Więc jeśli zdefiniujesz metodę coerce dla twojej klasy, 5 + instance_of_your_class będzie działało bez żadnych zmian w Fixnum # +.

Edycja: Oto przykład użycia przymusić:

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> 
+0

świetnie, to jest idealne, dzięki! – Peter

-1

Tak. Jeśli chcesz zmienić zachowanie na 5 + x, musisz przedefiniować + na czymkolwiek 5, ponieważ w rzeczywistości wywołujesz 5.+(x), ponieważ Ruby traktuje te operacje jako wywołania Mechanod.

0

RHS jest zmuszany i musi wdrożyć metody to_i która musi zwrócić odpowiednią wartość. Implementacja klasy Numeric dla to_int zakończy się nazwaniem jej jako częścią procesu dodawania, gdzie inne klasy zaangażowane są w RHS niż ścisłe potomkowie liczbowi.