[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: Making == symmetric?

Mark Wilson

10/1/2003 2:16:00 AM

Those more knowledgeable than me should correct what I've written below
if it's wrong.

On Tuesday, September 30, 2003, at 07:19 PM, Nathan Weston wrote:

> It has always bothered me that == is not symmetric in ruby:
> a == b is shorthand for a.==(b), while b == a is shorthand for
> b.==(a), and a and b might not agree on whether they are equal.

I think it is symmetric so long as you bear in mind that the method
belongs to the object and not to the variable that refers to the
object. See below.

> [snip]

> First of all: yes, this issue does come up in real code.
> Here's a quick example I ran into today:
>
> require "delegate"
> class Foo
> end
> class D < SimpleDelegator
> def initialize(obj)
> super(obj)
> end
> end
> f = Foo.new
> d = D.new(f)
> d == f #evaluates to true
> f == d #evaluates to false

I think you're mixing up variables and values. d refers to a D object
instantiated with a Foo object. f refers to the Foo object used to
instantiate the D object. The D object has an == method that checks its
value and compares it to the given value. When invoked by d==f, the D
object sees that its value is the Foo object and sees that f refers to
the Foo object and determines that they are the same object. In other
words the D object is the functional equivalent of an assignment to a
primitive variable.

The Foo object does not have a value other than its object id (I
think). When it queries the value of the variable d in performing the
== method, it gets the object id of the D object (I think). The two are
not equal. The proper comparison would be:

f.inspect==d.inspect

Another way of looking at it:

D.new(Foo.new) == Foo.new # false
Foo.new == D.new(Foo.new) # false



> I ran into a similar problem trying to implement perl6-style
> junctions: you end up with any(1,2,3) == 1 being true, but 1 ==
> any(1,2,3) being false.

I didn't follow the above point. There was an earlier discussion on the
list about perl6-style junctions that might be helpful.

> [snip]

Regards,

Mark


4 Answers

elbows

10/1/2003 4:07:00 PM

0

Mark Wilson <mwilson13@cox.net> wrote in message news:<3AA52722-F3B5-11D7-951C-000393876156@cox.net>...
> Those more knowledgeable than me should correct what I've written below
> if it's wrong.
>
> On Tuesday, September 30, 2003, at 07:19 PM, Nathan Weston wrote:
>
> > It has always bothered me that == is not symmetric in ruby:
> > a == b is shorthand for a.==(b), while b == a is shorthand for
> > b.==(a), and a and b might not agree on whether they are equal.
>
> I think it is symmetric so long as you bear in mind that the method
> belongs to the object and not to the variable that refers to the
> object. See below.

If == is symmetric, then (a == b) if and only if (b == a). In ruby,
this is not always the case, which can be very confusing.
I'm not sure what this has to do with the method belonging to the
object rather than the variable.

>
> > [snip]
>

[snip]

>
> I think you're mixing up variables and values. d refers to a D object
> instantiated with a Foo object. f refers to the Foo object used to
> instantiate the D object. The D object has an == method that checks its
> value and compares it to the given value. When invoked by d==f, the D
> object sees that its value is the Foo object and sees that f refers to
> the Foo object and determines that they are the same object. In other
> words the D object is the functional equivalent of an assignment to a
> primitive variable.

[snip]

I understand how and why things work the way they do in ruby -- I just
happen to think that way is wrong.

The issue in the above example is not whether f and d are equal (in
the code I am working on now, it would be convenient if they were, but
that's beside the point). The issue is that f and d (or rather, the
objects they refer to), don't agree on whether they are equal. I think
that is a bad thing.

Essentially what I am looking for is a way for an object, when asked
if it is equal to some other object, to answer "I don't know".

>
>
> > I ran into a similar problem trying to implement perl6-style
> > junctions: you end up with any(1,2,3) == 1 being true, but 1 ==
> > any(1,2,3) being false.
>
> I didn't follow the above point. There was an earlier discussion on the
> list about perl6-style junctions that might be helpful.
>

Admittedly I didn't elaborate on that point too much. I went back and
read the earlier discussion (which I actually started), and here is
the exact problem:

Suppose we have a method any(*args), which creates a junction object
of its arguments.

Then any("1", "2", "3") == "1" evaluates to true (which is correct).
However, "1" == any("1", "2", "3") evaluates to false (which is not
correct).

The problem is that String doesn't know about the Junction class, and
therefore assumes it is not equal to any instances of it. (Maybe it
looks for a to_str method first, or somesuch -- I don't know the
implementation details exactly). There is no way around this, no
matter how you implement Junction, because in the second case the
comparison is don exclusively by String -- none of Junction's methods
are ever called.

Under my solution, a comparison between a "1" and any("1", "2", "3"),
would first ask "1" if it knows how to compare itself to the junction.
The answer would be "no", since the string class doesn't know anything
about junctions. However, the junction does know how to compare itself
to a string, so the junction's comparison method would be called
(regardless of which side of the == the junction is on).

Nathan

Florian Gross

10/1/2003 7:00:00 PM

0

Moin!

Nathan Weston wrote:
>>> trying to implement perl6-style junctions
> Suppose we have a method any(*args), which creates a junction object
> of its arguments.
>
> Then any("1", "2", "3") == "1" evaluates to true (which is correct).
> However, "1" == any("1", "2", "3") evaluates to false (which is not
> correct).
>
> The problem is that String doesn't know about the Junction class, and
> therefore assumes it is not equal to any instances of it. (Maybe it
> looks for a to_str method first, or somesuch -- I don't know the
> implementation details exactly). There is no way around this, no
> matter how you implement Junction, because in the second case the
> comparison is don exclusively by String -- none of Junction's methods
> are ever called.

Junctions are interesting things to implement. (Even if it's
questionable whether they really make sense in Ruby when doing something
else than passing multiple objects to a method which only expects a
single one...)

I've actually implemented them already in a few lines of plain Ruby
code: http://rubyforge.org/projects...

I solved the problem of built-in methods not knowing what to do with
Junctions by plainly hiding them behind proxies -- this makes
interesting things like "food taste good".match(%w{foo bar qux}.any)
possible.

The problem with this approach is that it's quite ugly to implement and
that it might even cause some bad side-effects. (Because of this I
didn't include this in the actual Junction implementation itself.)

Oh, and to really make Junctions perl compatible you would need to
replace any method call including Junctions as parameters with a
Junction constructed of the results of the method call with all the
Junction's states anyway. (Perl6 doesn't pass Junctions into methods by
default because it fears that Junction logic might be confusing. (For
example in this code you could get both "foo!" and "bar!" if arg is a
Junction: puts "foo!" if arg == 1; puts "bar!" if arg == 2))

Regards,
Florian Groß


RichTravsky

4/18/2010 1:49:00 AM

0

Doug wrote:
>
> And a country where Jews aren't allowed to be, live or stay at all.

How about this?

http://individual.utoronto.ca/vivek/images/bush...

Doug

4/20/2010 6:08:00 PM

0

"RichTravsky" <traRvEsky@hotmMOVEail.com> wrote in message
news:4BCA64FD.DFCA290C@hotmMOVEail.com...
> Doug wrote:
>>
>> And a country where Jews aren't allowed to be, live or stay at all.
>
> How about this?
>
> http://individual.utoronto.ca/vivek/images/bush...

Dubya is Jewish? LOL.