From: elbows@... (Nathan Weston) Date: 2003-10-01T08:19:27+09:00 Subject: Making == symmetric? 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 diffening 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.