From: Michal Rokos Date: 2002-04-30T06:44:21+09:00 Subject: [RFC] Ranges - enable (10..-10) Hello, I've looked that negative ranges are not allowed in Ruby. I'd like to discuss, if it is possible permit them... Example: (10..-10).each |i| do puts i end does nothing in current Ruby (10..-10).step(2) does nothing in current Ruby This patch make the example works (and fixes some funny step's value like 0 (causes never ending loop) and < 0 (causes overroll). I'm waiting for your comments :-) Michal PS: This is initial version for me to see if you will agree with further development... Index: range.c =================================================================== RCS file: /src/ruby/range.c,v retrieving revision 1.32 diff -u -r1.32 range.c --- range.c 2002/04/24 04:54:14 1.32 +++ range.c 2002/04/29 20:59:42 @@ -74,11 +74,11 @@ rb_scan_args(argc, argv, "21", &beg, &end, &flags); /* Ranges are immutable, so that they should be initialized only once. */ - if (rb_ivar_defined(obj, id_beg)) { + if (RTEST(rb_ivar_defined(obj, id_beg))) { rb_name_error(rb_intern("initialized"), "`initialize' called twice"); } range_init(obj, beg, end, RTEST(flags)); - return Qnil; + return obj; } static VALUE @@ -231,59 +231,6 @@ } static VALUE -range_each(range) - VALUE range; -{ - VALUE b, e; - - b = rb_ivar_get(range, id_beg); - e = rb_ivar_get(range, id_end); - - if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */ - long end = FIX2LONG(e); - long i; - - if (!EXCL(range)) end += 1; - for (i=FIX2LONG(b); iend; i-=s) { + rb_yield(LONG2NUM(i)); + } + } else { + if (!EXCL(range)) end += 1; + for (i=beg; i', 1, e))) { + rb_yield(b); + b = rb_funcall(b, '-', 1, step); + } + } else { + if (!EXCL(range)) e = rb_funcall(e, '+', 1, INT2FIX(1)); + while (RTEST(rb_funcall(b, '<', 1, e))) { + rb_yield(b); + b = rb_funcall(b, '+', 1, step); + } + } + } else if (TYPE(b) == T_STRING) { VALUE args[5]; long iter[2]; @@ -343,8 +312,7 @@ iter[0] = 1; iter[1] = NUM2LONG(step); rb_iterate((VALUE(*)_((VALUE)))r_step_str, (VALUE)args, r_step_str_i, (VALUE)iter); - } - else { /* generic each */ + } else { /* generic each */ VALUE v = b; long lim = NUM2INT(step); long i; @@ -366,8 +334,14 @@ } } } - return range; +} + +static VALUE +range_each(range) + VALUE range; +{ + return range_step(0, NULL, range); } static VALUE -- -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Michal Rokos Czech Technical University, Prague E-mail:m.rokos@sh.cvut.cz ICQ:36118339 Jabber:majkl@jabber.sh.cvut.cz -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-