2010-03-27 39 views
5

Dưới đây là một số mã ví dụ:Mảng của Ruby. so sánh các yếu tố cho sự bình đẳng?

class Obj 
    attr :c, true 

    def == that 
    p '==' 
    that.c == self.c 
    end 
    def <=> that 
    p '<=>' 
    that.c <=> self.c 
    end 
    def equal? that 
    p 'equal?' 
    that.c.equal? self.c 
    end 
    def eql? that 
    p 'eql?' 
    that.c.eql? self.c 
    end 
end 

a = Obj.new 
b = Obj.new 

a.c = 1 
b.c = 1 

p [a] | [b] 

Nó in 2 đối tượng nhưng cần in 1 đối tượng. Không có phương thức so sánh nào được gọi. Làm thế nào là Array. so sánh cho bình đẳng?

Trả lời

6

Array#| được thực hiện sử dụng hashs. Vì vậy, để cho loại của bạn hoạt động tốt với nó (cũng như với hashmaps và hashsets), bạn sẽ phải triển khai eql? (mà bạn đã làm) và hash (mà bạn không làm). Cách tiến thẳng nhất để xác định hàm băm có ý nghĩa là chỉ trả về c.hash.

+0

Chỉ cần xác nhận - phương thức băm # Array của Ruby có đảm bảo rằng các giá trị sẽ bằng và chỉ khi nội dung của các mảng bằng nhau không? –

+0

@EricWalker No. Nó đảm bảo rằng hai mảng băm bằng nhau nếu (nhưng không chỉ nếu) cả hai mảng chứa các phần tử có cùng giá trị băm theo cùng thứ tự. Tuy nhiên điều này là không liên quan đến câu hỏi này như ở đây băm chỉ được gọi là trên các yếu tố, không bao giờ trên các mảng mình. – sepp2k

1

Lớp Mảng của Ruby được triển khai trong C và từ những gì tôi có thể biết, sử dụng bảng băm tùy chỉnh để kiểm tra sự bình đẳng khi so sánh các đối tượng trong |. Nếu bạn muốn thay đổi hành vi này, bạn phải viết phiên bản của riêng bạn sử dụng kiểm tra bình đẳng theo lựa chọn của bạn.

Để xem thực hiện đầy đủ Ruby Array#|: click here và tìm kiếm cho "rb_ary_or(VALUE ary1, VALUE ary2)"

0

Ruby đang gọi hàm băm và chúng đang trả về các giá trị khác nhau, vì chúng vẫn chỉ trả về object_id mặc định. Bạn sẽ cần phải def hash và trả về một cái gì đó phản ánh ý tưởng của bạn về những gì làm cho một Obj đáng kể.

>> class Obj2 < Obj 
>> def hash; t = super; p ['hash: ', t]; t; end 
>> end 
=> nil 
>> x, y, x.c, y.c = Obj2.new, Obj2.new, 1, 1 
=> [#<Obj2:0x100302568 @c=1>, #<Obj2:0x100302540 @c=1>, 1, 1] 
>> p [x] | [y] 
["hash: ", 2149061300] 
["hash: ", 2149061280] 
["hash: ", 2149061300] 
["hash: ", 2149061280] 
[#<Obj2:0x100302568 @c=1>, #<Obj2:0x100302540 @c=1>] 
Các vấn đề liên quan