From: elbows@... (Nathan Weston) Date: 2003-08-01T10:45:55+09:00 Subject: Re: Changing ==,>,<, etc That seems to work for Numeric types, but it doesn't help with other objects (Strings, for example). I'd like to be able to put any object inside a Disjunction or Conjunction. BTW, I am using ruby 1.6.8. Are there any relevant differences in 1.8? Nathan Daniel Carrera wrote in message news:<20030731184328.GB1297@math.umd.edu>... > I think I have an idea. I'm not sure about the implementation details: > > Example: 3 < any(1,2,4) > > 1) Create a Disjunction#<=> and mixin Enumerable so that you can write > things like: > > any(3) < any(1,2,4) > all(3) > any(1,2,4) > > 2) Create a Disjunction#coerce method so that the line: > 3 < any(1,2,4) > Is turned into the line: > all(3) > any(1,2,4) # It doesn't matter if it's any(3) or all(3). > > When Ruby sees "3 < any(1,2,4)" it'll look for Fixnum#coerce for help. > When it doesn't help, it'll look at Disjunction#coerce. Or, at least > that's what I think. > > The Disjunction#coerce would be written somewhat like this: > > class Disjunction > # WARNING: No error checking. > def coerce(other) > return all(other), self > end > end > > Cheers, > Daniel. > > > On Fri, Aug 01, 2003 at 03:22:36AM +0900, Nathan Weston wrote: > > The latest Perl exegesis > > (http://www.perl.com/pub/a/2003/07/29/exegesis6.html?page=4) > > introduces "junction types", which are really cool. > > In short, you can do expressions like (a == any(1,2,3)) or (a > > > all(1,2,3)) instead of (a == 1) or (a == 2) or (a == 3), etc. > > > > So of course, I immediately set out to do this in ruby. So, I whipped > > up a Disjunction class, and the any() function for syntactic sugar, > > and soon I could do: > > > > # 1 == any(1,2,3) > > true > > # 4 == any(1,2,3) > > false > > > > And all was well. But then I hit a snag: > > # 1 < any(1,2,3) > > ERR: (eval):1:in `<': Disjunction can't be coerced into Fixnum > > > > Fixnum#== seems to be smart enough to call Disjunction#==, which gets > > the behavior I want. Unfortunately, Fixnum#< is not, and neither are > > most of the <,>,== methods in the various built-in classes (i.e. > > String#== and Array#== both return false for any Junction class). > > > > Of course, with ObjectSpace and module_eval, I can redefine everyone's > > comparison methods to work properly, but this is kind of ugly. Also, > > if someone defines a new class after after I have done my ObjectSpace > > hack, they have to explicitly write their comparison methods to know > > about Junctions. > > > > Is there a better way to do this? > > > > If there's not a better way, should there be? > > I was thinking that perhaps all comparison methods should have a > > similar semantics, along the lines of: > > > > class Foo > > def ==(obj) > > if obj.is_a?(Foo) > > #I know how to compare myself to other Foo objects, > > #so I will do so > > return somevalue > > else > > #I don't know how to compare myself to non-Foo objects, > > #but maybe they know how to compare themselves to me -- > > #let's give them a chance > > return (obj == self) > > end > > end > > end > > > > Or at least, that's the basic idea. There also needs to be some way to > > bail out when neither class knows how to compare to the other -- > > either by returning false or throwing an exception. > > > > If all comparison methods worked this way, I could implement my > > Junction classes with no hacks, since objects that didn't know > > anything about Junctions would just let the Junction do the > > comparison. > > -- > Daniel Carrera | PGP: 6643 8C8B 3522 66CB D16C D779 2FDD 7DAC 9AF7 7A88 > Math PhD. UMD | http://www.math.umd.edu/~dcarrera/pgp.html > > * * * * * Weekly Smile * * * * * * * * * * * * * * * * * * * * * * * * > Sign in a hotel in Athens: > Visitors are expected to complain at the office between the hours > of 9 and 11 A.M. daily. > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *