PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Autres forums > Forum Programmation & Conception > comp.lang.ruby > How does Array#- do comparisons?
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
How does Array#- do comparisons?

Réponse
 
LinkBack Outils de la discussion
Vieux 31/03/2008, 03h37   #1
Adam Bender
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut How does Array#- do comparisons?

How does Array#- (as in, [1, 2, 3, 1, 1] - [1]) compare two objects to
see if they are equal? I would think the .eql? method, but I've
written a class that implements that method so that two different
objects with the same values are considered equal and '-' isn't
functioning as I would expect. A contrived example:

irb(main):004:0> class Hash
irb(main):005:1> def eql?(h)
irb(main):006:2> true
irb(main):007:2> end
irb(main):008:1> end
=> nil
irb(main):010:0> h1 = {'a' => 1}
=> {"a"=>1}
irb(main):011:0> h2 = {'a' => 1}
=> {"a"=>1}
irb(main):012:0> h1 == h2
=> true
irb(main):013:0> h1.eql? h2
=> true
irb(main):014:0> [h1] - [h2]
=> [{"a"=>1}]

I would expect [] as a result, just like the following:
irb(main):015:0> ["asdf"] - ["asdf"]
=> []

Thanks,

Adam

  Réponse avec citation
Vieux 31/03/2008, 07h58   #2
Stefano Crocco
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How does Array#- do comparisons?

On Monday 31 March 2008, Adam Bender wrote:
> How does Array#- (as in, [1, 2, 3, 1, 1] - [1]) compare two objects to
> see if they are equal? I would think the .eql? method, but I've
> written a class that implements that method so that two different
> objects with the same values are considered equal and '-' isn't
> functioning as I would expect. A contrived example:
>
> irb(main):004:0> class Hash
> irb(main):005:1> def eql?(h)
> irb(main):006:2> true
> irb(main):007:2> end
> irb(main):008:1> end
> => nil
> irb(main):010:0> h1 = {'a' => 1}
> => {"a"=>1}
> irb(main):011:0> h2 = {'a' => 1}
> => {"a"=>1}
> irb(main):012:0> h1 == h2
> => true
> irb(main):013:0> h1.eql? h2
> => true
> irb(main):014:0> [h1] - [h2]
> => [{"a"=>1}]
>
> I would expect [] as a result, just like the following:
> irb(main):015:0> ["asdf"] - ["asdf"]
> => []
>
> Thanks,
>
> Adam


It uses eql?. However, before calling it, it calls the hash method of the two
objects. If they return different values, they're considered different and
eql? is not called. If the two calls to hash return the same values, then eql?
is called. The reason is that two objects which are eql? should also have the
same hash value (see the ri documentation for Object#hash) and the comparison
of hash values is tried first because (I think) of efficiency.

This make me think one should always follow this rule:
"When you reimplement the eql? method, you should also reimplement the hash
method (or at least, make sure the hash method returns the same value for
objects which are eql?)"

This is an example:

class C

attr_reader :x
def initialize x
@x = x
end

def hash
@x.to_i
end

def eql? other
self.class == other.class and @x.eql? other.x
end

end

a = [ C.new(1), C.new(2)]
p (a - [C.new(1)])

In this case, two objects of class C are eql? if their instance variables @x
have the same value. Since hash returns @x (converted to an int), two objects
which are eql? have hash methods which return the same value.

I hope this s

Stefano


  Réponse avec citation
Vieux 31/03/2008, 10h26   #3
Robert Klemme
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: How does Array#- do comparisons?

2008/3/31, Adam Bender <abender@gmail.com>:
> How does Array#- (as in, [1, 2, 3, 1, 1] - [1]) compare two objects to
> see if they are equal? I would think the .eql? method, but I've
> written a class that implements that method so that two different
> objects with the same values are considered equal and '-' isn't
> functioning as I would expect. A contrived example:
>
> irb(main):004:0> class Hash
> irb(main):005:1> def eql?(h)
> irb(main):006:2> true
> irb(main):007:2> end
> irb(main):008:1> end
> => nil
> irb(main):010:0> h1 = {'a' => 1}
> => {"a"=>1}
> irb(main):011:0> h2 = {'a' => 1}
> => {"a"=>1}
> irb(main):012:0> h1 == h2
> => true
> irb(main):013:0> h1.eql? h2
> => true
> irb(main):014:0> [h1] - [h2]
> => [{"a"=>1}]
>
> I would expect [] as a result, just like the following:
> irb(main):015:0> ["asdf"] - ["asdf"]
> => []


Another illustration of Stefano's point:

irb(main):001:0> class Foo; end
=> nil
irb(main):002:0> [Foo.new] - [Foo.new]
=> [#<Foo:0x7ff994b0>]
irb(main):003:0> class Foo
irb(main):004:1> def eql?(o) true end
irb(main):005:1> end
=> nil
irb(main):006:0> [Foo.new] - [Foo.new]
=> [#<Foo:0x7ff80988>]
irb(main):007:0> class Foo
irb(main):008:1> def hash;0 end
irb(main):009:1> end
=> nil
irb(main):010:0> [Foo.new] - [Foo.new]
=> []

Kind regards

robert

--
use.inject do |as, often| as.you_can - without end

  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 02h49.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,11668 seconds with 11 queries