how to compare two object instances? is"m1.to_yaml.eql?(m2.to_yaml)" a good way?

G

Greg Hauptmann

Hi,

What's an easy way to compare for equality two object instances (that
haven't been saved yet). Or in other words pretty much just two
object instances. I've tried "==" and "eql?" on the objects directly
and this doesn't work.

How about: "m1.to_yaml.eql?(m2.to_yaml)" Is this the simplest way?

(i.e. leveraging the ability to serialize the object to a yaml string)

tks
 
R

Robert Klemme

What's an easy way to compare for equality two object instances (that
haven't been saved yet).

Why do you believe equivalence has something to do with persistence?
Or in other words pretty much just two
object instances. I've tried "==" and "eql?" on the objects directly
and this doesn't work.

How about: "m1.to_yaml.eql?(m2.to_yaml)" Is this the simplest way?

(i.e. leveraging the ability to serialize the object to a yaml string)

You do not mention what classes these objects belong to. However, the
proper way is to implement ==, eql? and hash in order to provide correct
equivalence semantics. The easy way is to use Struct which will
implement those methods for you based on the fields you define.

Kind regards

robert
 
G

Greg Hauptmann

2009/9/5 Robert Klemme said:
Why do you believe equivalence has something to do with persistence?

It's only the instances I want to compare of instances of a Rails
model class which haven't been saved (i.e. if they had been saved they
may have then received their ID attribute values which may have been
different). But yes my question is really generic to any given
custom developed class I may happen to write.
You do not mention what classes these objects belong to. =A0However, the
proper way is to implement =3D=3D, eql? and hash in order to provide corr= ect
equivalence semantics. =A0The easy way is to use Struct which will implem= ent
those methods for you based on the fields you define.

So I think you're saying if I can convert the 2 instances of class X I
want to compare to 2 instances of a Struct I create (with the same
attributes of those in my class X) then I can just leverage the
already implemented code in the Struct class for "=3D=3D"? Is this what
you were meaning?

tks
 
V

Vahagn Hayrapetyan

Have you tried using obj_1.hash == obj_2.hash ?

Also, what do you mean by "saving" the object? Persisting it as a byte
stream, a string, or in a database using ORM?

/ Vahagn
 
G

Greg Hauptmann

I think the saving/persistence comment of mine diverted the focus of
the question. Robert's comment " the proper way is to implement ==,
eql? and hash in order to provide correct equivalence semantics. The
easy way is to use Struct which will implement those methods for you
based on the fields you define." seem to be the key I was just
asking for clarification re how the Struct can be used to save time in
implementing....
 
G

Greg Hauptmann

actually I just saw this posted on
"http://www.reddit.com/r/ruby/comments/9540i/ruby_developers_make_sure_you_define_eql_and_hash/"
that might be good...


def eql?(other)
return false unless other.class == self.class
return false unless other.instance_variables == self.instance_variables
self.instance_variables.each do |var|
self_var = self.instance_variable_get(var)
other_var = other.instance_variable_get(var)
return false unless self_var.eql?(other_var)
end
true;
end
 
R

Robert Klemme

It's only the instances I want to compare of instances of a Rails
model class which haven't been saved (i.e. if they had been saved they
may have then received their ID attribute values which may have been
different). But yes my question is really generic to any given
custom developed class I may happen to write.


So I think you're saying if I can convert the 2 instances of class X I
want to compare to 2 instances of a Struct I create (with the same
attributes of those in my class X) then I can just leverage the
already implemented code in the Struct class for "=="? Is this what
you were meaning?

No, I meant, if you want to be lazy you can implement your classes by
using Struct. But your approach would work as well.

I don't know whether and how AR implements ==, eql? and hash - chances
are that they only compare the primary key in the database which
probably would not help you - but this is just a guess.

If you need to convert your objects anyway, then you could also use
Arrays, e.g.

a, b = [x,y].map {|o| [o.foo, o.bar, o.baz]}

puts( a == b )

Of course, things get more complicated if your class X does not only
contain primitive data (such as Fixnum, String etc.) but other AR
created objects as well. Maybe it's better to then implement a to_xyz
method in the class which returns something which can be compared.
There is a ton of options out there but for one I'm not a Rails user and
then we do not have much detail about your use case.

Kind regards

robert
 
G

Greg Hauptmann

2009/9/5 Robert Klemme said:
If you need to convert your objects anyway, then you could also use Arrays,
e.g.

a, b = [x,y].map {|o| [o.foo, o.bar, o.baz]}

puts( a == b )

Thanks Robert - this looks like a good way to go then.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top