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: [email protected]
[mailto:[email protected]] On Behalf Of Davy Brion
Sent: Thursday, September 09, 2010 4:46 AM
To: [email protected]
Subject: Re: [Ironruby-core] object equality
On Thu, Sep 9, 2010 at 1:44 PM, Davy Brion
<[email protected]<mailto:[email protected]>> 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
<[email protected]<mailto:[email protected]>> 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
<[email protected]<mailto:[email protected]>> 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
<[email protected]<mailto:[email protected]>> 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
<[email protected]<mailto:[email protected]>> wrote:
> 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.testcla...@new(5)<mailto:ruby.testcla...@new(5)>;
> dynamic test2 = ruby.testcla...@new(5)<mailto:ruby.testcla...@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?
> _______________________________________________
> Ironruby-core mailing list
> [email protected]<mailto:[email protected]>
> http://rubyforge.org/mailman/listinfo/ironruby-core
_______________________________________________
Ironruby-core mailing list
[email protected]<mailto:[email protected]>
http://rubyforge.org/mailman/listinfo/ironruby-core
_______________________________________________
Ironruby-core mailing list
[email protected]<mailto:[email protected]>
http://rubyforge.org/mailman/listinfo/ironruby-core
_______________________________________________
Ironruby-core mailing list
[email protected]<mailto:[email protected]>
http://rubyforge.org/mailman/listinfo/ironruby-core
_______________________________________________
Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core