2010-09-30 22 views
4

Selon Ruby Set documentation de la classe, « == Retourne true si deux ensembles sont égaux L'égalité de chaque couple d'éléments est défini en fonction de l'objet # eql ?.Ruby Set classe: égalité des ensembles

Le. l'essence de ce qui peut être démontrée en utilisant des objets de date, où des ensembles contenant différents objets Date, mais avec la même date comparer à l'égalité:

require 'set' 
d1 = Date.today    # => Thu, 30 Sep 2010 
puts d1.object_id   # => 2211539680 
d2 = Date.today + 1   # => Fri, 01 Oct 2010 
puts d2.object_id   # => 2211522320 
set1 = Set.new([d1, d2]) 

d11 = Date.today    # => Thu, 30 Sep 2010 
puts d11.object_id   # => 2211489080 
d12 = Date.today + 1   # => Fri, 01 Oct 2010 
puts d12.object_id   # => 2211469380 
set2 = Set.new([d12, d11]) 

set1 == set2     # => true 

Mais en utilisant mes propres objets, où j'ai Codé la eql méthode pour comparer seulement? certains attributs, je ne peux pas le faire fonctionner

class IpDet 

    attr_reader :ip, :gateway 

    def initialize(ip, gateway, netmask, reverse) 
     @ip = ip 
     @gateway = gateway 
     @netmask = netmask 
     @reverse = reverse 
    end 

    def eql?(other) 
     if @ip = other.ip && @gateway == other.gateway 
      return true 
     else 
      return false 
     end 
    end 
end 



ipdet1 = IpDet.new(123456, 123457, 123458, 'example.com') 
ipdet2 = IpDet.new(234567, 2345699, 123458, 'nil') 

ipdet11 = IpDet.new(123456, 123457, 777777, 'other_domain.com') 
ipdet12 = IpDet.new(234567, 2345699, 777777, 'example.com') 

puts "ipdet1 is equal to ipdet11: #{ipdet1.eql?(ipdet11)}" 
puts "ipdet2 is equal to ipdet12: #{ipdet2.eql?(ipdet12)}" 


set1 = Set.new([ipdet1, ipdet2]) 
set2 = Set.new([ipdet11, ipdet12]) 

puts "set 1 is equal to set2: #{set1 == set2}" 

La sortie que je reçois de ce qui précède est:

ipdet1 is equal to ipdet11: true 
ipdet2 is equal to ipdet12: true 
set 1 is equal to set2: false 

Toute personne idées?

Répondre

10

Lorsque vous remplacez eql?, vous avez aussi toujours besoin de passer outre hash telle que si o1.eql?(o2) est vrai, o1.hash == o2.hash est également vrai.

Par exemple, votre méthode de hachage pourrait ressembler à ceci:

def hash 
    [@ip, @gateway].hash 
end 

vous avez également une faute de frappe dans votre méthode eql?: @ip = other.ip devrait être @ip == other.ip.

également un StyleNote mineur: if condition then true else false end est équivalent à un peu condition, de sorte que votre méthode eql? peut simplement être définie comme

def eql?(other) 
    @ip == other.ip && @gateway == other.gateway 
end 
+0

C'est génial, merci beaucoup. J'avais en quelque sorte l'impression que je devais faire quelque chose avec du hasch, mais je ne savais pas quoi, et j'étais un peu nerveuse à l'idée de démolir tout le caboodle en jouant avec. Donc je suppose que je vais lire à ce sujet maintenant, donc je le comprends correctement. – stephenr