Forum: IronRuby object equality

Posted by Davy Brion (Guest)
on 2010-09-09 10:33
(Received via mailing list)
If i have the following class in ruby:

class TestClass
  def initialize(value)
    @value = value
  end

  def ==(other)
    return false if other.nil?
    self.value == other.value
  end

  protected

  def value
    @value
  end
end

test1 = TestClass.new(5)
test2 = TestClass.new(5)
p test1 == test2
p test1 != test2

the output is:
true
false

if i do this in .NET:

dynamic test1 = ruby.TestClass.@new(5);
dynamic test2 = ruby.TestClass.@new(5);

var equals = test1 == test2;
var differs = test1 != test2;

both equals and differs are true

i'm going to create an issue about this, but i do need to get this
working... is there a temporary workaround that i can use for now?
Posted by Will Green (hotgazpacho)
on 2010-09-09 12:21
(Received via mailing list)
Testing for object equality in C# is different than it is in Ruby. In
C#, you need to override both Object.Equals and Object.GetHashCode (I
forget which is used when, but I do recall that the compiler complains
if you override one and not the other). So, when you bring your Ruby
object into C# and compare them, C# doesn't see an override for Equals
on your object, and thus uses Object.Equals (which is often what you
don't want). Try defining an equals method on your Ruby object, or
alias it to ==.

I suspect that the == method on your Ruby object does not map to
Equals when you bring into C#. And I'm not sure that it should.

Thoughts?

--
Will Green
http://hotgazpacho.org/
Posted by Davy Brion (Guest)
on 2010-09-09 12:53
(Received via mailing list)
the problem isn't with checking wether 2 objects are equal (though you
indeed need to define an Equals method on your ruby object if you want 
the
comparison to work with a direct call to .Equals... doing == in C#
definitely uses the == method of your ruby object) but it is with the !=
check.  In ruby, using != calls == and inverts the result of that. 
Doing !=
in C# on a ruby object doesn't seem to do the same thing.

I'm also not entirely sure how it _should_ be... but as far as i can 
tell,
right now, i can't get equality checks working properly with ruby 
objects.

if a == b is true, then a != b should always be false
if a.Equals(b) is true, then !a.Equals(b) should always be false

if there's another way to get this behavior working in C# for ruby 
objects,
i'd love to hear about it since it's pretty important for something i'm
trying to do :)
Posted by Will Green (hotgazpacho)
on 2010-09-09 13:10
(Received via mailing list)
Then it would appear that in C#, using the != operator on two instances 
of
Ruby objects does not call the == method on the first Ruby object and 
invert
the result.

Can you switch to using equals as a work-around?

Not sure of the semantics around == vs .Equals in C#, but I know there 
is a
semantic difference between == and eql? in Ruby.

--
Will Green
http://hotgazpacho.org/



On Sep 9, 2010, at 6:52 AM, Davy Brion <ralinx@davybrion.com> wrote:

the problem isn't with checking wether 2 objects are equal (though you
indeed need to define an Equals method on your ruby object if you want 
the
comparison to work with a direct call to .Equals... doing == in C#
definitely uses the == method of your ruby object) but it is with the !=
check.  In ruby, using != calls == and inverts the result of that. 
Doing !=
in C# on a ruby object doesn't seem to do the same thing.

I'm also not entirely sure how it _should_ be... but as far as i can 
tell,
right now, i can't get equality checks working properly with ruby 
objects.

if a == b is true, then a != b should always be false
if a.Equals(b) is true, then !a.Equals(b) should always be false

if there's another way to get this behavior working in C# for ruby 
objects,
i'd love to hear about it since it's pretty important for something i'm
trying to do :)
Posted by Davy Brion (Guest)
on 2010-09-09 13:44
(Received via mailing list)
by default, == does a reference check in C#, unless you override it to 
do a
value based check (which you typically implement in Equals)

in C#, if you want == and != to work properly you need to implement them
both.  In ruby, you obviously can't implement !=, but i had (naievely
perhaps) expected that IronRuby would preserve the Ruby behavior when
calling == on an object which implements it.  I _think_ that would be 
the
best way to handle this, though there might be very valid reasons as to 
why
this isn't the case at the moment.

defining an Equals method on the ruby class which delegates to == works, 
but
it is somewhat weird since most people use the == and != operators to 
check
for equality.

perhaps i'm better off getting rid of the == implementation and solely
providing an Equals implementation
Posted by Davy Brion (Guest)
on 2010-09-09 13:46
(Received via mailing list)
On Thu, Sep 9, 2010 at 1:44 PM, Davy Brion <ralinx@davybrion.com> wrote:

> defining an Equals method on the ruby class which delegates to == works,
> but it is somewhat weird since most people use the == and != operators to
> check for equality.
>
> perhaps i'm better off getting rid of the == implementation and solely
> providing an Equals implementation
>
>
though the downside of that is that the ruby class doesn't stick to 
ruby's
idioms when it comes to equality checks, which hurts its usage from 
other
ruby code :s
Posted by Tomas Matousek (Guest)
on 2010-09-10 07:10
(Received via mailing list)
If any of the operands of == or != are typed to dynamic C# emits a call 
to dynamic site with the corresponding operation. If the left hand side 
is a Ruby object then this dynamic operation is translated to a Ruby 
method call “==” or “!=”, respectively.
The latest version of IronRuby (built from github sources) is compatible 
with MRI 1.9.2 in the way “!=” method is implemented: BasicObject#!= 
calls == and negates the result. You can also provide your own 
implementation of != method if its behavior should be different. This 
semantics is compatible with DLR dynamic operations and everything works 
as expected:

dynamic equatable = Engine.Execute(@"
class RubyEquatable
    def initialize val
      @val = val
    end

    def ==(other)
      @val == other
    end
end

RubyEquatable.new(100)
");

Assert((bool)( equatable == 100));
Assert(!(bool)( equatable == 101));
Assert(!(bool)( equatable != 100));
Assert((bool)( equatable != 100));

Tomas

From: ironruby-core-bounces@rubyforge.org 
[mailto:ironruby-core-bounces@rubyforge.org] On Behalf Of Davy Brion
Sent: Thursday, September 09, 2010 4:46 AM
To: ironruby-core@rubyforge.org
Subject: Re: [Ironruby-core] object equality


On Thu, Sep 9, 2010 at 1:44 PM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:
by default, == does a reference check in C#, unless you override it to 
do a value based check (which you typically implement in Equals)

in C#, if you want == and != to work properly you need to implement them 
both.  In ruby, you obviously can't implement !=, but i had (naievely 
perhaps) expected that IronRuby would preserve the Ruby behavior when 
calling == on an object which implements it.  I _think_ that would be 
the best way to handle this, though there might be very valid reasons as 
to why this isn't the case at the moment.

defining an Equals method on the ruby class which delegates to == works, 
but it is somewhat weird since most people use the == and != operators 
to check for equality.

perhaps i'm better off getting rid of the == implementation and solely 
providing an Equals implementation


though the downside of that is that the ruby class doesn't stick to 
ruby's idioms when it comes to equality checks, which hurts its usage 
from other ruby code :s


On Thu, Sep 9, 2010 at 1:10 PM, William Green 
<will@hotgazpacho.org<mailto:will@hotgazpacho.org>> wrote:
Then it would appear that in C#, using the != operator on two instances 
of Ruby objects does not call the == method on the first Ruby object and 
invert the result.

Can you switch to using equals as a work-around?

Not sure of the semantics around == vs .Equals in C#, but I know there 
is a semantic difference between == and eql? in Ruby.

--
Will Green
http://hotgazpacho.org/



On Sep 9, 2010, at 6:52 AM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:
the problem isn't with checking wether 2 objects are equal (though you 
indeed need to define an Equals method on your ruby object if you want 
the comparison to work with a direct call to .Equals... doing == in C# 
definitely uses the == method of your ruby object) but it is with the != 
check.  In ruby, using != calls == and inverts the result of that. 
Doing != in C# on a ruby object doesn't seem to do the same thing.

I'm also not entirely sure how it _should_ be... but as far as i can 
tell, right now, i can't get equality checks working properly with ruby 
objects.

if a == b is true, then a != b should always be false
if a.Equals(b) is true, then !a.Equals(b) should always be false

if there's another way to get this behavior working in C# for ruby 
objects, i'd love to hear about it since it's pretty important for 
something i'm trying to do :)
On Thu, Sep 9, 2010 at 12:20 PM, William Green 
<will@hotgazpacho.org<mailto:will@hotgazpacho.org>> wrote:
Testing for object equality in C# is different than it is in Ruby. In
C#, you need to override both Object.Equals and Object.GetHashCode (I
forget which is used when, but I do recall that the compiler complains
if you override one and not the other). So, when you bring your Ruby
object into C# and compare them, C# doesn't see an override for Equals
on your object, and thus uses Object.Equals (which is often what you
don't want). Try defining an equals method on your Ruby object, or
alias it to ==.

I suspect that the == method on your Ruby object does not map to
Equals when you bring into C#. And I'm not sure that it should.

Thoughts?

--
Will Green
http://hotgazpacho.org/



On Sep 9, 2010, at 4:33 AM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:

>   end
> p test1 == test2
>
> var equals = test1 == test2;
> var differs = test1 != test2;
>
> both equals and differs are true
>
> i'm going to create an issue about this, but i do need to get this working... is there a temporary workaround that i can use for now?
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
> http://rubyforge.org/mailman/listinfo/ironruby-core
_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core
Posted by Tomas Matousek (Guest)
on 2010-09-10 07:11
(Received via mailing list)
There is indeed a typo… the last line should read:
Assert((bool)( equatable != 101));

Tomas

From: Tomas Matousek
Sent: Thursday, September 09, 2010 10:10 PM
To: ironruby-core@rubyforge.org
Subject: RE: [Ironruby-core] object equality

If any of the operands of == or != are typed to dynamic C# emits a call 
to dynamic site with the corresponding operation. If the left hand side 
is a Ruby object then this dynamic operation is translated to a Ruby 
method call “==” or “!=”, respectively.
The latest version of IronRuby (built from github sources) is compatible 
with MRI 1.9.2 in the way “!=” method is implemented: BasicObject#!= 
calls == and negates the result. You can also provide your own 
implementation of != method if its behavior should be different. This 
semantics is compatible with DLR dynamic operations and everything works 
as expected:

dynamic equatable = Engine.Execute(@"
class RubyEquatable
    def initialize val
      @val = val
    end

    def ==(other)
      @val == other
    end
end

RubyEquatable.new(100)
");

Assert((bool)( equatable == 100));
Assert(!(bool)( equatable == 101));
Assert(!(bool)( equatable != 100));
Assert((bool)( equatable != 100));

Tomas

From: ironruby-core-bounces@rubyforge.org 
[mailto:ironruby-core-bounces@rubyforge.org] On Behalf Of Davy Brion
Sent: Thursday, September 09, 2010 4:46 AM
To: ironruby-core@rubyforge.org
Subject: Re: [Ironruby-core] object equality


On Thu, Sep 9, 2010 at 1:44 PM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:
by default, == does a reference check in C#, unless you override it to 
do a value based check (which you typically implement in Equals)

in C#, if you want == and != to work properly you need to implement them 
both.  In ruby, you obviously can't implement !=, but i had (naievely 
perhaps) expected that IronRuby would preserve the Ruby behavior when 
calling == on an object which implements it.  I _think_ that would be 
the best way to handle this, though there might be very valid reasons as 
to why this isn't the case at the moment.

defining an Equals method on the ruby class which delegates to == works, 
but it is somewhat weird since most people use the == and != operators 
to check for equality.

perhaps i'm better off getting rid of the == implementation and solely 
providing an Equals implementation


though the downside of that is that the ruby class doesn't stick to 
ruby's idioms when it comes to equality checks, which hurts its usage 
from other ruby code :s


On Thu, Sep 9, 2010 at 1:10 PM, William Green 
<will@hotgazpacho.org<mailto:will@hotgazpacho.org>> wrote:
Then it would appear that in C#, using the != operator on two instances 
of Ruby objects does not call the == method on the first Ruby object and 
invert the result.

Can you switch to using equals as a work-around?

Not sure of the semantics around == vs .Equals in C#, but I know there 
is a semantic difference between == and eql? in Ruby.

--
Will Green
http://hotgazpacho.org/



On Sep 9, 2010, at 6:52 AM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:
the problem isn't with checking wether 2 objects are equal (though you 
indeed need to define an Equals method on your ruby object if you want 
the comparison to work with a direct call to .Equals... doing == in C# 
definitely uses the == method of your ruby object) but it is with the != 
check.  In ruby, using != calls == and inverts the result of that. 
Doing != in C# on a ruby object doesn't seem to do the same thing.

I'm also not entirely sure how it _should_ be... but as far as i can 
tell, right now, i can't get equality checks working properly with ruby 
objects.

if a == b is true, then a != b should always be false
if a.Equals(b) is true, then !a.Equals(b) should always be false

if there's another way to get this behavior working in C# for ruby 
objects, i'd love to hear about it since it's pretty important for 
something i'm trying to do :)
On Thu, Sep 9, 2010 at 12:20 PM, William Green 
<will@hotgazpacho.org<mailto:will@hotgazpacho.org>> wrote:
Testing for object equality in C# is different than it is in Ruby. In
C#, you need to override both Object.Equals and Object.GetHashCode (I
forget which is used when, but I do recall that the compiler complains
if you override one and not the other). So, when you bring your Ruby
object into C# and compare them, C# doesn't see an override for Equals
on your object, and thus uses Object.Equals (which is often what you
don't want). Try defining an equals method on your Ruby object, or
alias it to ==.

I suspect that the == method on your Ruby object does not map to
Equals when you bring into C#. And I'm not sure that it should.

Thoughts?

--
Will Green
http://hotgazpacho.org/



On Sep 9, 2010, at 4:33 AM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:

>   end
> p test1 == test2
>
> var equals = test1 == test2;
> var differs = test1 != test2;
>
> both equals and differs are true
>
> i'm going to create an issue about this, but i do need to get this working... is there a temporary workaround that i can use for now?
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
> http://rubyforge.org/mailman/listinfo/ironruby-core
_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core
Posted by Davy Brion (Guest)
on 2010-09-10 09:49
(Received via mailing list)
great to hear, and already looking forward to the next release :)

just wondering though, you mentioned that it's possible to provide your 
own
implementation of !=.  how would one do that? if i try to define a !=
method, i get an 'unexpected !=' error

On Fri, Sep 10, 2010 at 7:09 AM, Tomas Matousek <
Posted by Tomas Matousek (Guest)
on 2010-09-10 18:43
(Received via mailing list)
You need MRI 1.9.* or IronRuby built from github sources.
Then this just works

def !=(other)
end

Tomas

From: ironruby-core-bounces@rubyforge.org 
[mailto:ironruby-core-bounces@rubyforge.org] On Behalf Of Davy Brion
Sent: Friday, September 10, 2010 12:46 AM
To: ironruby-core@rubyforge.org
Subject: Re: [Ironruby-core] object equality

great to hear, and already looking forward to the next release :)

just wondering though, you mentioned that it's possible to provide your 
own implementation of !=.  how would one do that? if i try to define a 
!= method, i get an 'unexpected !=' error
On Fri, Sep 10, 2010 at 7:09 AM, Tomas Matousek 
<Tomas.Matousek@microsoft.com<mailto:Tomas.Matousek@microsoft.com>> 
wrote:
If any of the operands of == or != are typed to dynamic C# emits a call 
to dynamic site with the corresponding operation. If the left hand side 
is a Ruby object then this dynamic operation is translated to a Ruby 
method call “==” or “!=”, respectively.
The latest version of IronRuby (built from github sources) is compatible 
with MRI 1.9.2 in the way “!=” method is implemented: BasicObject#!= 
calls == and negates the result. You can also provide your own 
implementation of != method if its behavior should be different. This 
semantics is compatible with DLR dynamic operations and everything works 
as expected:

dynamic equatable = Engine.Execute(@"
class RubyEquatable
    def initialize val
      @val = val
    end

    def ==(other)
      @val == other
    end
end

RubyEquatable.new(100)
");

Assert((bool)( equatable == 100));
Assert(!(bool)( equatable == 101));
Assert(!(bool)( equatable != 100));
Assert((bool)( equatable != 100));

Tomas

From: 
ironruby-core-bounces@rubyforge.org<mailto:ironruby-core-bounces@rubyforge.org> 
[mailto:ironruby-core-bounces@rubyforge.org<mailto:ironruby-core-bounces@rubyforge.org>] 
On Behalf Of Davy Brion
Sent: Thursday, September 09, 2010 4:46 AM
To: ironruby-core@rubyforge.org<mailto:ironruby-core@rubyforge.org>
Subject: Re: [Ironruby-core] object equality


On Thu, Sep 9, 2010 at 1:44 PM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:
by default, == does a reference check in C#, unless you override it to 
do a value based check (which you typically implement in Equals)

in C#, if you want == and != to work properly you need to implement them 
both.  In ruby, you obviously can't implement !=, but i had (naievely 
perhaps) expected that IronRuby would preserve the Ruby behavior when 
calling == on an object which implements it.  I _think_ that would be 
the best way to handle this, though there might be very valid reasons as 
to why this isn't the case at the moment.

defining an Equals method on the ruby class which delegates to == works, 
but it is somewhat weird since most people use the == and != operators 
to check for equality.

perhaps i'm better off getting rid of the == implementation and solely 
providing an Equals implementation


though the downside of that is that the ruby class doesn't stick to 
ruby's idioms when it comes to equality checks, which hurts its usage 
from other ruby code :s


On Thu, Sep 9, 2010 at 1:10 PM, William Green 
<will@hotgazpacho.org<mailto:will@hotgazpacho.org>> wrote:
Then it would appear that in C#, using the != operator on two instances 
of Ruby objects does not call the == method on the first Ruby object and 
invert the result.

Can you switch to using equals as a work-around?

Not sure of the semantics around == vs .Equals in C#, but I know there 
is a semantic difference between == and eql? in Ruby.

--
Will Green
http://hotgazpacho.org/



On Sep 9, 2010, at 6:52 AM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:
the problem isn't with checking wether 2 objects are equal (though you 
indeed need to define an Equals method on your ruby object if you want 
the comparison to work with a direct call to .Equals... doing == in C# 
definitely uses the == method of your ruby object) but it is with the != 
check.  In ruby, using != calls == and inverts the result of that. 
Doing != in C# on a ruby object doesn't seem to do the same thing.

I'm also not entirely sure how it _should_ be... but as far as i can 
tell, right now, i can't get equality checks working properly with ruby 
objects.

if a == b is true, then a != b should always be false
if a.Equals(b) is true, then !a.Equals(b) should always be false

if there's another way to get this behavior working in C# for ruby 
objects, i'd love to hear about it since it's pretty important for 
something i'm trying to do :)
On Thu, Sep 9, 2010 at 12:20 PM, William Green 
<will@hotgazpacho.org<mailto:will@hotgazpacho.org>> wrote:
Testing for object equality in C# is different than it is in Ruby. In
C#, you need to override both Object.Equals and Object.GetHashCode (I
forget which is used when, but I do recall that the compiler complains
if you override one and not the other). So, when you bring your Ruby
object into C# and compare them, C# doesn't see an override for Equals
on your object, and thus uses Object.Equals (which is often what you
don't want). Try defining an equals method on your Ruby object, or
alias it to ==.

I suspect that the == method on your Ruby object does not map to
Equals when you bring into C#. And I'm not sure that it should.

Thoughts?

--
Will Green
http://hotgazpacho.org/



On Sep 9, 2010, at 4:33 AM, Davy Brion 
<ralinx@davybrion.com<mailto:ralinx@davybrion.com>> wrote:

>   end
> p test1 == test2
>
> var equals = test1 == test2;
> var differs = test1 != test2;
>
> both equals and differs are true
>
> i'm going to create an issue about this, but i do need to get this working... is there a temporary workaround that i can use for now?
> _______________________________________________
> Ironruby-core mailing list
> Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
> http://rubyforge.org/mailman/listinfo/ironruby-core
_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core

_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core



_______________________________________________
Ironruby-core mailing list
Ironruby-core@rubyforge.org<mailto:Ironruby-core@rubyforge.org>
http://rubyforge.org/mailman/listinfo/ironruby-core
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.