2010-02-24 11 views
30

Tengo una clase Foo con algunas variables miembro. Cuando todos los valores en dos instancias de la clase son iguales, quiero que los objetos sean "iguales". Entonces me gustaría que estos objetos sean claves en mi hash. Cuando pruebo esto, el hash trata cada instancia como desigual.¿Cómo hacer que la instancia del objeto sea una clave hash en Ruby?

h = {} 
f1 = Foo.new(a,b) 
f2 = Foo.new(a,b) 

f1 y f2 deben ser iguales en este punto.

h[f1] = 7 
h[f2] = 8 
puts h[f1] 

debe imprimir 8

Respuesta

54

Ver http://ruby-doc.org/core/classes/Hash.html

Hash utiliza key.eql? para probar las claves para la igualdad . Si necesita utilizar instancias de sus propias clases como claves en un Hash, , se recomienda que defina ambos el eql? y métodos hash. El método hash debe tener la propiedad de que a.eql? (B) implica a.hash == b.hash.

El eql? El método es fácil de implementar: devuelve verdadero si todas las variables miembro son iguales. Para el método hash, use [@ data1, @ data2] .hash como sugiere Marc-Andre en los comentarios.

+0

Explicación perfecta. =) – Mereghost

+8

Bueno, excepto que el hash devuelto debe ser un fixnum, así que es mejor usar exclusive o en lugar de sum (que podría desbordarse a bignum). Alternativamente, use 'Array # hash', como' [@ data1, @ data2] .hash', por ejemplo. –

+0

Buen punto. La adición de hashes individuales juntos también tiene el peligro de que la misma suma pueda resultar de diferentes hash individuales (3 + 2 = 5 y 1 + 4 = 5). Usar Array # hash como sugiere Marc-Andre haría que la solución sea más completa. – Mark

-3

Añadir un método llamado hash 'a su clase:

class Foo 
    def hash 
    return whatever_munge_of_instance_variables_you_like 
    end 
end 

Esto funciona de la manera que ha solicitado y no generar diferentes claves hash para objetos diferentes, pero idénticos.

+4

También debe definir el método eql? De una manera que sea coherente con el método hash. Además, el método hash debe devolver un Fixnum, o lo hará romper uniq. – ChrisPhoenix

Cuestiones relacionadas