2012-12-21 16 views
7

Bu soruyu yanıtlamak için bir girişimde: How can I make the set difference insensitive to case?, Kümelere duyarsız dizeler kümesi oluşturmaya çalışırken kümeler ve dizelerle denemeler yapıyordum. Ancak String sınıfını yeniden açtığım için, bir kümeye bir dize eklediğimde özel yöntemlerimden hiçbiri çağrılmıyor. Aşağıdaki kodda çıktı görmüyorum, fakat işletmecilerden en az birinin çalıştırılmaya aşırı yüklediğimi tahmin ettim. Bu neden?bir dizi dizgiler ve yeniden açılıyor Dize

DÜZENLEME: Özel bir sınıf oluşturursam, sözgelimi, hash yöntemini vb. Tanımladığım String2 olarak adlandırırsam, nesneyi bir kümeye eklediğimde bu yöntemler çağrılır. Neden String değil? Set için source code baktığımızda

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' 

cevap

4

, depolanmak üzere basit bir karma kullanır: yerine açılma yapmanız gerekenler StringSet açıktır gibi

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

Yani görünüyor. Bunu test etmedim ama size doğru bir fikir vermelidir:

class MySet < Set 
    def add(o) 
    super(o.is_a?(String) ? o.downcase : o) 
    end 
end 
: açıklamalarda belirtildiği gibi, bu çok daha basit bir şekilde uygulanabilir

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

Edit

+1

Basit bir 'süper (o.is_a? (String)? Obelkilendirme: o) 'daha iyi bir fikir olabilir. –

+0

teşekkürler. O çalışır, evet. Özel bir sınıf oluşturursam, örneğin bir karma yöntemi tanımladığım String2 gibi bir nesne oluşturursam, nesneyi bir kümeye eklediğimde bu yöntemler çağrılır. Niye ya? (Sorumu düzenledim). – akonsu

+0

Ruby kaynağı (https://github.com/ruby/ruby/blob/trunk/hash.c#L1195) bir ipucu verebilir. Görünüşe göre, String, MRI'da hash anahtarları olarak özel muamele görüyor. – Luke