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

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

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

obj1.inspect.gsub(re, ‘’) == obj2.inspect.gsub(re, ‘’)

Sorry should be ‘sub’, not ‘gsub’:

obj1.inspect.sub(re, ‘’) == obj2.inspect.sub(re, ‘’)

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

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

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

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.)

Ilan B. 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:

Lobosque Lucas wrote:

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 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

On 12/19/06, Jeremy W. [email protected] wrote:

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

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