From: elbows@... (Nathan Weston) Date: 2003-08-01T23:11:54+09:00 Subject: Re: Changing ==,>,<, etc At the moment, Disjunction doesn't know anything about its contents -- it just does def ==(obj) @contents.each { |c| if c == obj return true end } return false end At the moment, any("1", "2", "3") == "1" works fine. But if I do the reverse: "1" == any("1", "2", "3") it just returns false. String#== doesn't even try to call a coerce method. String#< gives a type error, again without trying to call Disjunction#coerce. Looking at the API docs, it seems that only Numeric types have coerce. Nathan Daniel Carrera wrote in message news:<20030801021020.GA1643@math.umd.edu>... > How is your Disjunction class implemented? Does it understand Strings? > Can I type this?: > > all("c") < any("d", "e", "f") > > If so, then the Disjunction#coerce should work. If not, then the problem > is in the implementation of Disjunction I think. > > Daniel. > > On Fri, Aug 01, 2003 at 10:45:55AM +0900, Nathan Weston wrote: > > 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. > > > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * > > -- > 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. > * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *