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