2010-12-09 80 views
2

我想在Ruby中實現一個可與任何Fixnum,(反之亦然)進行比較的類(使用<=>運算符)。這將最終在一個範圍內使用。這裏是我班的輪廓:Ruby對象與Fixnum類似

class N 
    include Comparable 
    attr :offset 
    def initialize(offset = 0) 
    @offset = offset 
    end 
    def succ 
    N.new(@offset + 1) 
    end 
    def +(offset) 
    N.new(@offset + offset) 
    end 
    def <=>(other) 
    return @offset <=> other.offset if other.kind_of? N 
    return 1 # N is greater than everything else 
    end 
end 

def n; N.new(0); end 

現在1..nn..n+2n..999使用時,但不是這樣的偉大工程。這是由於n <=> 1工作,但1 <=> n沒有(返回)。

有沒有什麼辦法可以讓Fixnum把我的N類當作可比對象?你的想法是讚賞:)

回答

6

如果你想實現自己的號碼類型,你必須實現coerce

class N 
    def coerce(other) 
    return N.new(other), self 
    end 
end 

n = N.new 

1 <=> n # => -1 

所有核心庫Ruby的內建數種,所有數字類型的標準庫,以及所有第三方號碼類型使用coerce協議來查找一個通用類型,以便使運營商可以交換+,*==,並且-/ nd <=>對稱。

我不太清楚N應該是什麼語義,所以上面的實現只是一個例子。

0

好吧,我做了一個小猴子補丁(自由修補;),似乎已經解決了我現在的問題。

class Fixnum 
    def <=>(other) 
    return -1 if other.kind_of? N 
    return -1 if self < other 
    return 0 if self == other 
    return 1 if self > other 
    end 
end 

輸出似乎不如預期,並沒有在Fixnum內部工作,據我可以告訴破壞任何東西。任何更好的想法/意見,隨時張貼'時間。

1 <=> n # => -1 
1 <=> 1 # => 0 
1 <=> 2 # => -1 
2 <=> 1 # => 1 
1 == 1 # => true 
1 == 2 # => false 
1 < 2 # => true 
1 > 2 # => false 
+0

`return N <=> self if other.kind_of? N` – Nakilon 2010-12-09 08:47:08

+2

Yuck。 *如果*你絕對*必須*猴子補丁,你應該*至少*確保不違反方法的公共契約。 – 2010-12-09 09:37:51