From: Robert Dober Date: 2006-11-26T18:15:58+09:00 Subject: Re: Patch for HalfOrder, help please! ------=_Part_4292_407402.1164532556123 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-Disposition: inline On 11/26/06, Nobuyoshi Nakada wrote: > > Hi, > lib/tsort.rb may help you? No but I have to appologize for the confusion. > [2 halforder.patch.tar.bz2 ] > > It was empty. Sorry about that, I will try to be less confused this time -- > Nobu Nakada > > I have patched my ruby with a HalfOrder module thaught as an optional replacement of the #== paradigm. Halforder relies on the definition of <= to define all other comparision operators. Note that if for all a,b in a class a <=b || b <=a holds we have the normal order, only that we can implement domains where a <= b || b <=a is not true for all a,b. This cannot be done with <=> where a<=>b has to return x from {-1,0,1}. Performance is not a concern. As this seemed to be a very easy task for someone who never has looked at the ruby code before off I went :) VALUE rb_mHalfOrder; static ID less_than; ... static VALUE ho_gt(x, y) VALUE x, y; { VALUE c; if (x == y) return Qfalse; // y <= x ? c = rb_funcall(y, less_than, 1, x); if (NIL_P(c)) return Qfalse; if ( c == Qfalse ) return c; // x <= y ? c = rb_funcall(x, less_than, 1, y); if (NIL_P(c)) return Qtrue; if ( c == Qfalse ) return Qtrue; return Qfalse; } The only problem is that the following definition static VALUE ho_equal(x, y) VALUE x, y; { VALUE c; if (x == y) return Qtrue; // x <= y ? c = rb_funcall(x, less_than, 1, y); if ( NIL_P(c) ) return Qfalse; if ( c == Qfalse ) return c; // y <= x ? c = rb_funcall(y, less_than, 1, x); if ( NIL_P(c) ) return Qfalse; if ( c == Qfalse ) return c; return Qtrue; } ... void Init_HalfOrder() { rb_mHalfOrder = rb_define_module("HalfOrder"); rb_define_method(rb_mHalfOrder, "==", ho_equal, 1); rb_define_method(rb_mHalfOrder, ">", ho_gt, 1); rb_define_method(rb_mHalfOrder, ">=", ho_ge, 1); rb_define_method(rb_mHalfOrder, "<", ho_lt, 1); less_than = rb_intern("<="); } does not override the #== of the class we are mixed in. I found no way to do this but I would love to do this. Thank you Robert -- The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man. - George Bernard Shaw ------=_Part_4292_407402.1164532556123 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline

On 11/26/06, Nobuyoshi Nakada <nobu@ruby-lang.org> wrote:
Hi,

 

<cut>
lib/tsort.rb may help you?

No but  I have to appologize for the confusion.

> [2 halforder.patch.tar.bz2 <application/x-bzip2 (base64)>]

It was empty.

Sorry about that, I will try to be less confused this time

--
Nobu Nakada

I have patched my ruby with a HalfOrder module thaught as an optional replacement of the  #== paradigm.

<explanation of my motivation>
Halforder relies on the definition of <= to define all other comparision operators.
Note that if for all a,b in a class  a <=b || b <=a holds we have the normal order, only that we can implement domains where a <= b || b <=a is not true for all a,b.
This cannot be done with <=> where a<=>b has to return x from {-1,0,1}.
Performance is not a concern.
</explanation>

As this seemed to be a very easy task for someone who never has looked at the ruby code before off I went :)
<code>
VALUE rb_mHalfOrder;
static ID less_than;
...
static VALUE
ho_gt(x, y)
    VALUE x, y;
{
    VALUE c;

    if (x == y) return Qfalse;

    // y <= x ?
    c = rb_funcall(y, less_than, 1, x);

    if (NIL_P(c)) return Qfalse;
    if ( c == Qfalse ) return c;

    // x <= y ?
    c = rb_funcall(x, less_than, 1, y);

    if (NIL_P(c)) return Qtrue;
    if ( c == Qfalse ) return Qtrue;

    return Qfalse;
}
</code>
 
The only problem is that the following definition
<code>
static VALUE
ho_equal(x, y)
    VALUE x, y;
{
    VALUE c;

    if (x == y) return Qtrue;

    // x <= y ?
    c = rb_funcall(x, less_than, 1, y);
    if ( NIL_P(c) ) return Qfalse;
    if ( c == Qfalse ) return c;

    // y <= x ?
    c = rb_funcall(y, less_than, 1, x);
    if ( NIL_P(c) ) return Qfalse;
    if ( c == Qfalse ) return c;
    return Qtrue;
}
...
void
Init_HalfOrder()
{
    rb_mHalfOrder = rb_define_module("HalfOrder");
    rb_define_method(rb_mHalfOrder, "==", ho_equal, 1);
    rb_define_method(rb_mHalfOrder, ">", ho_gt, 1);
    rb_define_method(rb_mHalfOrder, ">=", ho_ge, 1);
    rb_define_method(rb_mHalfOrder, "<", ho_lt, 1);

    less_than = rb_intern("<=");
}
</code>
does not override the #== of the class we are mixed in.


I found no way to do this but I would love to do this.

Thank you
Robert
--
The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore all progress depends on the unreasonable man.

- George Bernard Shaw ------=_Part_4292_407402.1164532556123--