2012-12-21 28 views
7

Trong một nỗ lực để trả lời câu hỏi này: How can I make the set difference insensitive to case?, tôi đã thử nghiệm với các bộ và chuỗi, cố gắng để có một chuỗi không phân biệt chữ hoa chữ thường. Nhưng vì một lý do nào đó khi tôi mở lại lớp String, không có phương thức tùy chỉnh nào của tôi được gọi khi tôi thêm một chuỗi vào một tập hợp. Trong đoạn code dưới đây tôi không thấy đầu ra, nhưng tôi đã dự kiến ​​ít nhất một trong các toán tử mà tôi đã quá tải để được gọi. Tại sao điều này?một tập hợp các chuỗi và mở lại chuỗi

EDIT: Nếu tôi tạo một lớp tùy chỉnh, hãy nói, String2, nơi tôi xác định phương thức băm, v.v., các phương thức này được gọi khi tôi thêm đối tượng của mình vào tập hợp. Tại sao không String?

require 'set' 

class String 
    alias :compare_orig :<=> 
    def <=> v 
    p '<=>' 
    downcase.compare_orig v.downcase 
    end 

    alias :eql_orig :eql? 
    def eql? v 
    p 'eql?' 
    eql_orig v 
    end 

    alias :hash_orig :hash 
    def hash 
    p 'hash' 
    downcase.hash_orig 
    end 
end 

Set.new << 'a' 

Trả lời

4

Nhìn vào source code cho Set, nó sử dụng một băm đơn giản để lưu trữ:

def add(o) 
    @hash[o] = true 
    self 
end 

Vì vậy, nó trông giống như những gì bạn cần làm thay vì mở String là mở Set. Tôi đã không kiểm tra này, nhưng nó sẽ cho bạn những ý tưởng đúng:

class MySet < Set 
    def add(o) 
    if o.is_a?(String) 
     @hash[o.downcase] = true 
    else 
     @hash[o] = true 
    end 
    self 
    end 
end 

Sửa

Như đã đề cập trong các ý kiến, điều này có thể được thực hiện một cách đơn giản hơn nhiều:

class MySet < Set 
    def add(o) 
    super(o.is_a?(String) ? o.downcase : o) 
    end 
end 
+1

Một đơn giản 'siêu (o.is_a? (String)? O.downcase: o)' có thể là một ý tưởng tốt hơn. –

+0

cảm ơn. có hiệu quả, vâng. Nếu tôi tạo một lớp tùy chỉnh, ví dụ, String2, trong đó tôi định nghĩa một phương thức băm, vv, các phương thức này được gọi khi tôi thêm đối tượng của tôi vào một tập hợp. Tại sao? (Tôi đã chỉnh sửa câu hỏi của mình). – akonsu

+0

Nguồn Ruby (https://github.com/ruby/ruby/blob/trunk/hash.c#L1195) có thể cung cấp một đầu mối. Có vẻ như 'String' có được điều trị đặc biệt như các khóa băm trong MRI. – Luke

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