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

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

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

Greg H. wrote:

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

On 05.09.2009 11:52, Greg H. wrote:

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

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…

2009/9/5 Robert K. [email protected]:

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

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?

tks

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

On 05.09.2009 13:07, Greg H. wrote:

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.

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

2009/9/5 Robert K. [email protected]:

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.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs