From: Tanaka Akira Date: 2003-02-12T01:51:13+09:00 Subject: Re: Operator reordering, good idea? (was Re: ruby-dev summary 19457-19539) In article <20030211150727.GC16278@debian>, Sam Roberts writes: >> method call is just a implementation. > > It's a fundamental property of the language. When you understand that > operators are method calls, you know how to program in Ruby. Yes. So equality for == must be implemented by method call. Equality assumes commutativity. Unfortunately commutativity is difficult to implement because method call is not symmetrical as you said. Especially it needs collaboration if left hand class has different author to right hand class. String is very difficult case because the author of String (matz) cannot know == policy for other class written by an user. But fortunately == should be commutative, matz can know the policy by calling == method of the other class. Note that equality against string is only meaningful for string like object, the == call is only applied for classes which have to_str method which is the sign of "it can be treated as a string in parameter". I know only one example which should be equal to String. require 'delegate' d = SimpleDelegator.new("abc") p d == "abc" #=> true p "abc" == d #=> true Since d delegates method calls to "abc", it behaves as String even if it is actually not a String. Note that to_str method of d is defined as delegation because String has to_str. > What I'm trying to say is this seems like a special purpose hack. It > *doesn't* make == commutative: it makes == for 3 builtin classes > commutative. I think it shows "how to implement commutativity by method call". However it is somewhat restricted because Numeric has more powerful system: coercion. > The original example was > > Exception == String > > Well, what does this mean? I don't know, what does Exception say it's == > operator does? An Exception is clearly NOT a string, so at some level > this doesn't make sense, but I guess it defined something reasonable. > If not, I get Object.==, like in ALL OTHER CASES EXCEPT THREE BUILTIN > TYPES. It is true that "an Exception is clearly NOT a string". So it returns false. > String == Exception > > What does this mean? Well, String.== tries to coerce everything into a > string before comparing itself to it. I know what that means. No. String#== tried to coerce an object which have to_str method, not everything. However we found the coercion was problematic because it led non-commutative behavior. By historical reason, Exception has to_str. Exception#to_str is used as follows: /pattern/ =~ exception Such codes exist because $! was string in old days. Anyway the equality between String and Exception is intended and String#== and Exception#== implements it now. Do you have better way to implement the equality? Note that non-historical example of to_str is my pathname.rb. It defines Pathname class which has to_str. So Pathname object can be passed to various method which takes a string: File.open, etc. Since it is not equal to string like exception, Pathname#== returns false if an argument is a String. Thanks to current String#==, String#== returns false if an argument is a Pathname. -- Tanaka Akira