2012-04-14 31 views
5

Theo số Set doc, các thành phần trong một bộ được so sánh bằng cách sử dụng eql?.Đặt với quy tắc tùy chỉnh

Tôi có một lớp học như:

class Foo 
    attr_accessor :bar, :baz 

    def initialize(bar = 1, baz = 2) 
    @bar = bar 
    @baz = baz 
    end 

    def eql?(foo) 
    bar == foo.bar && baz == foo.baz 
    end 
end 

Trong giao diện điều khiển:

f1 = Foo.new 
f2 = Foo.new 
f1.eql? f2 #=> true 

Nhưng ...

s = Set.new 
s << f1 
s << f2 
s.size #=> 2 

f1 bằng f2, s nên không bao gồm cả của họ.

Làm cách nào để làm cho các yếu tố từ chối set có quy tắc tùy chỉnh?

Trả lời

7

Các tài liệu mà bạn liên kết đến nói một cách rõ ràng (tôi nhấn mạnh):

Các bình đẳng của mỗi cặp vợ chồng của các yếu tố được xác định theo Object#eql?
Object#hash, vì Set sử dụng Hash như lưu trữ.

Nếu bạn thêm một phương pháp hash đến lớp học của bạn mà trả về giá trị tương tự cho eql? đối tượng, nó hoạt động:

# With your current class 

f1, f2 = Foo.new, Foo.new 
p f1.eql?(f2) 
#=> true 
p f1.hash==f2.hash 
#=> false 
p Set[f1,f2].length 
#=> 2 

# Fix the problem 
class Foo 
    def hash 
    [bar,hash].hash 
    end 
end 

f1, f2 = Foo.new, Foo.new 
p f1.eql?(f2) 
#=> true 
p f1.hash==f2.hash 
#=> true 
p Set[f1,f2].length 
#=> 1 

Thành thật mà nói tôi chưa bao giờ có một cảm giác tuyệt vời cho cách viết một phương thức tốt tùy chỉnh hash khi có nhiều giá trị.

+0

vì vậy tôi nên làm gì? – apneadiving

+0

@apneadiving Xem chỉnh sửa của tôi. – Phrogz

+3

Bạn không thể sử dụng '[bar, baz] .hash' làm băm không? –

0

Theo sách Ngôn ngữ lập trình Ruby (đồng tác giả của Yukihiro Matsumoto, người tạo ngôn ngữ Ruby) công thức đa mục đích cho phương pháp băm liên quan đến một số hằng số (17/37) hằng số sử dụng. Ví dụ cho giải pháp gợi ý sẽ như thế nào:

def hash 
    code = 17 
    code = 37*code + @bar.hash 
    code = 37*code + @baz.hash 
    code 
end 

Vì vậy, nói chung chúng ta lặp đi lặp lại "code = 37 * Mã + @ x.hash" dòng cho mỗi biến dụ đáng kể (@x).

+0

btw: nó được đề cập rằng cách tiếp cận này được chuyển thể từ sách Java hiệu quả của Joshua Bloch (Prentice Hall) – Kotu

Các vấn đề liên quan