From: Austin Ziegler Date: 2003-10-01T08:54:32+09:00 Subject: Re: Making == symmetric? On Wed, 1 Oct 2003 08:19:27 +0900, 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 have an idea as to how to fix this, and was thinking of posting an RCR > on rubygarden, but I thought I'd post here first and see if I've missed > any major problems. > > 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 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. > > My proposed solution is this: > Instead of a == b being shorthand for a.==(b), it should be shorthand for > Kernel::compare(a, b). > > def compare(a,b) > if a.can_compare_to?(b) > return a.compare_to(b) > elsif b.can_compare_to?(a) > return b.compare_to(a) > else > return false > end > end > > > This way, a class is only responsible for comparing itself to other > classes it knows about. This allows a lot more flexibility, because you > can define new classes that introduce their own semantics for equality > w.r.t existing classes (i.e., you can make a new class that is equal to > some strings, without having to change String to know about the new > class). > > Compare this to the current situation, where an object is responsible for > comparing itself to any kind of object. In this situation, the only > sensible response for a class that you know nothing about is "false", > which limits flexibility, and can lead to == being asymmetric. > > Of course, this solution isn't perfect -- if a and b both know about each > other, but have differing ideas of equality, then a == b and b == a will > still return different results. But that's a lot easier to avoid than the > problems which arise under the current handling of ==. > > This solution might be extended to other operators that should be > symmetric, as well (such as +), but == is the most widely used and I > think the most important to fix. For most binary operators, #coerce would seem to work (so long as the binary operator exists in both classes), but not for ==. Perhaps that would be the way to handle this? -austin -- austin ziegler * austin@halostatue.ca * Toronto, ON, Canada software designer * pragmatic programmer * 2003.09.30 * 19.47.10