Compare two objects without take its ID in consideration

Is there a way to compare two objects without take its ID in
consideration? For example:

#<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
#<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">

It'll return false, because the object ID is different. But i want it to
return true, because the arguments (is it the right name?) are all
equal.

Thanks

···

--
Posted via http://www.ruby-forum.com/.

Lobosque Lucas wrote:

Is there a way to compare two objects without take its ID in
consideration? For example:

#<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
#<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">

It'll return false, because the object ID is different. But i want it to
return true, because the arguments (is it the right name?) are all
equal.

Thanks

You can overwrite the == method:

def ==(other_obj)
    true if self.str == other_obj.str and self.mdfel == other_obj.mdfel and self.name == other_obj.name
end

Lobosque,

     Please use the method eql? for this purpose. If you use eql? you'll get true and if you use equal? you'll get false, under the case you mentioned.

Shiwei
(The views expressed are my own and not necessarily those of Oracle and its affiliates.)

Lobosque Lucas wrote:

···

Is there a way to compare two objects without take its ID in
consideration? For example:

#<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
#<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">

It'll return false, because the object ID is different. But i want it to
return true, because the arguments (is it the right name?) are all
equal.

Thanks

It's not particularly nice but you could just do:

re = /:[^\s]*/
obj1.inspect.gsub(re, '') == obj2.inspect.gsub(re, '')

···

--
Posted via http://www.ruby-forum.com/.

Lobosque Lucas wrote:

Is there a way to compare two objects without take its ID in
consideration? For example:

#<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
#<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">

It'll return false, because the object ID is different. But i want it to
return true, because the arguments (is it the right name?) are all
equal.

Thanks

class Game_Esper
  def ==(other)
    @str==other.str && @mdfel==other.mdfel && @name==other.name
  end
end

If you have more state than this, I would suggest a looping construct
instead..

hope this helps

ilan

···

--
Posted via http://www.ruby-forum.com/\.

Lobosque Lucas wrote:

Is there a way to compare two objects without take its ID in
consideration? For example:

#<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
#<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">

It'll return false, because the object ID is different. But i want it to
return true, because the arguments (is it the right name?) are all
equal.

This is one pattern I use, and (because it defines #eql? and #hash) it also gives you the hashing behavior you will probably want to go with it:

   module ContentEquality
     def hash
       content.hash
     end

     def eql?(other)
       other.class == self.class and content.eql? other.content
     end

     def ==(other)
       other.class == self.class and content == other.content
     end
   end

   class Game
     include ContentEquality
     def initialize str, mdfel, name
       @str, @mdfel, @name = str, mdfel, name
     end

     def content
       [@str, @mdfel, @name]
     end
   end

   g1 = Game.new "foo", "bar", "baz"
   g2 = Game.new "foo", "bar", "baz"

   p g1 == g2 # ==> true

   h = {}
   h[g1] = true
   p h[g2] # ==> true

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

confirm that
(1) the question was perfectly correct and normal (well I guess)
(2) Jeremy's answer too.
It just stroke me that maybe OP would have preferred not to post this
question and having followed a link in a hypothetical FAQ

...
Object Equality, what is ==, what keys are considered equal in a Hash, look
here ==> class Object - RDoc Documentation

if that would not have helped her/him (I am abstracting from your post
Lucas) I guess any question posted would have been answered too.

Are there some folks kind of imagining the usefulness of such a collection
to be posted regularly, it might be tagged clearly e.g. [RUBY-FAQ-L0] and be
filtered out by your mail client if you are not interested.
If the FAQ is really good it might make it to the ruby site :wink:

Cheers
Robert

···

On 12/19/06, Jeremy Wells <jwells@servalsystems.co.uk> wrote:

Lobosque Lucas wrote:
> Is there a way to compare two objects without take its ID in
> consideration? For example:
>
> #<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
> #<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">
>
> It'll return false, because the object ID is different. But i want it to
> return true, because the arguments (is it the right name?) are all
> equal.
>
> Thanks
>
You can overwrite the == method:

def ==(other_obj)
    true if self.str == other_obj.str and self.mdfel == other_obj.mdfel
and self.name == other_obj.name
end

Sorry for making some noise here, but before doing so please let me

--
"The real romance is out ahead and yet to come. The computer revolution
hasn't started yet. Don't be misled by the enormous flow of money into bad
defacto standards for unsophisticated buyers using poor adaptations of
incomplete ideas."

- Alan Kay

obj1.inspect.gsub(re, '') == obj2.inspect.gsub(re, '')

Sorry should be 'sub', not 'gsub':

  obj1.inspect.sub(re, '') == obj2.inspect.sub(re, '')

···

--
Posted via http://www.ruby-forum.com/\.

A little more robust ...

def ==( other )
  return false unless Game_Esper === other

  self.instance_variables.each do |v|
    return false unless self.instance_variable_get(v) ==
        other.instance_variable_get(v)
  end
  true
end

Blessings,
TwP

···

On 12/19/06, Jeremy Wells <jwells@servalsystems.co.uk> wrote:

Lobosque Lucas wrote:
> Is there a way to compare two objects without take its ID in
> consideration? For example:
>
> #<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
> #<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">
>
> It'll return false, because the object ID is different. But i want it to
> return true, because the arguments (is it the right name?) are all
> equal.
>
> Thanks
>
You can overwrite the == method:

def ==(other_obj)
    true if self.str == other_obj.str and self.mdfel == other_obj.mdfel
and self.name == other_obj.name
end

Ilan Berci wrote:

class Game_Esper
  def ==(other)
    @str==other.str && @mdfel==other.mdfel && @name==other.name
  end
end

If you have more state than this, I would suggest a looping construct
instead..

hope this helps

ilan

Actually, after submitting this, I realized that if 2 objects are equal
they should return the same hash, adjust accordingly :slight_smile:

···

--
Posted via http://www.ruby-forum.com/\.

Hi --

···

On Tue, 19 Dec 2006, Robert Dober wrote:

On 12/19/06, Jeremy Wells <jwells@servalsystems.co.uk> wrote:

Lobosque Lucas wrote:
> Is there a way to compare two objects without take its ID in
> consideration? For example:
>
> #<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
> #<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">
>
> It'll return false, because the object ID is different. But i want it to
> return true, because the arguments (is it the right name?) are all
> equal.
>
> Thanks
>
You can overwrite the == method:

def ==(other_obj)
    true if self.str == other_obj.str and self.mdfel == other_obj.mdfel
and self.name == other_obj.name
end

Sorry for making some noise here, but before doing so please let me

confirm that
(1) the question was perfectly correct and normal (well I guess)
(2) Jeremy's answer too.
It just stroke me that maybe OP would have preferred not to post this
question and having followed a link in a hypothetical FAQ

Why not the real FAQ? http://www.rubygarden.org/faq

David

--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
    aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)

Can you explain me what is happening in that code? thanks

···

--
Posted via http://www.ruby-forum.com/.

A little, little more robust ...

def ==( other )
  return false unless self.class === other

  self.instance_variables.each do |v|
    return false unless self.instance_variable_get(v) ==
        other.instance_variable_get(v)
  end
  true
end

Blessings,
TwP

···

On 12/19/06, Tim Pease <tim.pease@gmail.com> wrote:

On 12/19/06, Jeremy Wells <jwells@servalsystems.co.uk> wrote:
> Lobosque Lucas wrote:
> > Is there a way to compare two objects without take its ID in
> > consideration? For example:
> >
> > #<Game_Esper:0xdcc7e0 @str=6, @mdfel = 0, @name = "Ifrit"> ==
> > #<Game_Esper:0xeda51e @str=6, @mdfel = 0, @name = "Ifrit">
> >
> > It'll return false, because the object ID is different. But i want it to
> > return true, because the arguments (is it the right name?) are all
> > equal.
> >
> > Thanks
> >
> You can overwrite the == method:
>
> def ==(other_obj)
> true if self.str == other_obj.str and self.mdfel == other_obj.mdfel
> and self.name == other_obj.name
> end
>

I just simply and stupidly ignored its existence, I looked for a link from
ruby-lang.org and I missed any reference in the ML, maybe that can be
changed?
Thx in any case!

Robert

···

On 12/19/06, dblack@wobblini.net <dblack@wobblini.net> wrote:

>> Sorry for making some noise here, but before doing so please let me
> confirm that
> (1) the question was perfectly correct and normal (well I guess)
> (2) Jeremy's answer too.
> It just stroke me that maybe OP would have preferred not to post this
> question and having followed a link in a hypothetical FAQ

Why not the real FAQ? http://www.rubygarden.org/faq

This just gets the representation of both of the objects as strings (the
'inspect') part. Then it strips out the Object ID (the 'sub') part using
a regular expression. It's a bit ugly though.

It would be better to add an attribute to your object which acts as a
identifier for that object (in the real world), then you can simply
compare that to check two objects are the same. For example:

obj1.my_id == obj2.my_id

Hope that makes sense,

Mark

···

--
Posted via http://www.ruby-forum.com/.

careful:

   harp:~ > cat a.rb
   class C
     def initialize
       @this = self
     end
     def ==( other )
       return false unless self.class === other
       self.instance_variables.each do |v|
         return false unless self.instance_variable_get(v) ==
             other.instance_variable_get(v)
       end
       true
     end
   end

   C.new == C.new

   harp:~ > ruby a.rb
   a.rb:8:in `==': stack level too deep (SystemStackError)
           from a.rb:10:in `=='
           from a.rb:8:in `=='
           from a.rb:10:in `=='
           from a.rb:8:in `=='
           from a.rb:10:in `=='
           from a.rb:8:in `=='
           from a.rb:10:in `=='
           from a.rb:8:in `=='
            ... 2489 levels...
           from a.rb:8:in `=='
           from a.rb:10:in `=='
           from a.rb:8:in `=='
           from a.rb:16

i prefer this pattern for the self documenting properties:

   harp:~ > cat a.rb
   class C
     %w[ a b c ].each{|a| attr a}
     def initialize a, b, c
       @a, @b, @c = a, b, c
     end
     CMP_ATTRS = %w[ a b c ]
     def == other
       begin
         x = CMP_ATTRS.map{|a| send a }
         y = CMP_ATTRS.map{|a| other.send a }
         x == y
       rescue
         false
       end
     end
   end

   p( C.new(1,2,3) == C.new(1,2,3) )
   p( C.new(1,2,3) == C.new(2,3,4) )

   harp:~ > ruby a.rb
   true
   false

though it too suffers from cyclical structures... sigh.

-a

···

On Wed, 20 Dec 2006, Tim Pease wrote:

A little, little more robust ...

def ==( other )
return false unless self.class === other

self.instance_variables.each do |v|
  return false unless self.instance_variable_get(v) ==
      other.instance_variable_get(v)
end
true
end

--
if you find yourself slandering anybody, first imagine that your mouth is
filled with excrement. it will break you of the habit quickly enough. - the
dalai lama

Infinite recursion only bothers me when I have a finite processor :wink:

Yeah, you can shoot yourself in the foot no matter how careful you
are. I did like Joel's "ContentEquality" pattern elsewhere in this
thread. I'm going to have to adopt that one.

Blessings,
TwP

···

On 12/19/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

i prefer this pattern for the self documenting properties:

   harp:~ > cat a.rb
   class C
     %w[ a b c ].each{|a| attr a}
     def initialize a, b, c
       @a, @b, @c = a, b, c
     end
     CMP_ATTRS = %w[ a b c ]
     def == other
       begin
         x = CMP_ATTRS.map{|a| send a }
         y = CMP_ATTRS.map{|a| other.send a }
         x == y
       rescue
         false
       end
     end
   end

   p( C.new(1,2,3) == C.new(1,2,3) )
   p( C.new(1,2,3) == C.new(2,3,4) )

   harp:~ > ruby a.rb
   true
   false

though it too suffers from cyclical structures... sigh.