[前][次][番号順一覧][スレッド一覧]

ruby-changes:2616

From: ko1@a...
Date: 5 Dec 2007 15:15:59 +0900
Subject: [ruby-changes:2616] nobu - Ruby:r14107 (ruby_1_8, trunk): * range.c (step_i, range_step): support non-fixnum steps.

nobu	2007-12-05 15:15:23 +0900 (Wed, 05 Dec 2007)

  New Revision: 14107

  Modified files:
    branches/ruby_1_8/ChangeLog
    branches/ruby_1_8/range.c
    branches/ruby_1_8/version.h
    trunk/ChangeLog
    trunk/range.c

  Log:
    * range.c (step_i, range_step): support non-fixnum steps.
      [ruby-talk:282100]


  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/range.c?r1=14107&r2=14106
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/ChangeLog?r1=14107&r2=14106
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=14107&r2=14106
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/range.c?r1=14107&r2=14106
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8/version.h?r1=14107&r2=14106

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 14106)
+++ ChangeLog	(revision 14107)
@@ -1,3 +1,8 @@
+Wed Dec  5 15:15:21 2007  Nobuyoshi Nakada  <nobu@r...>
+
+	* range.c (step_i, range_step): support non-fixnum steps.
+	  [ruby-talk:282100]
+
 Wed Dec  5 14:25:11 2007  Koichi Sasada  <ko1@a...>
 
 	* compile.c (iseq_compile_each): fix typo.
Index: range.c
===================================================================
--- range.c	(revision 14106)
+++ range.c	(revision 14107)
@@ -247,10 +247,16 @@
 static VALUE
 step_i(VALUE i, void *arg)
 {
-    long *iter = (long *)arg;
+    VALUE *iter = arg;
 
-    iter[0]--;
-    if (iter[0] == 0) {
+    if (FIXNUM_P(iter[0])) {
+	iter[0] -= INT2FIX(1) & ~FIXNUM_FLAG;
+    }
+    else {
+	VALUE one = INT2FIX(1);
+	iter[0] = rb_funcall(iter[0], '-', 1, &one);
+    }
+    if (iter[0] == INT2FIX(0)) {
 	rb_yield(i);
 	iter[0] = iter[1];
     }
@@ -297,15 +303,22 @@
     e = RANGE_END(range);
     if (rb_scan_args(argc, argv, "01", &step) == 0) {
 	step = INT2FIX(1);
+	unit = 1;
     }
-
-    unit = NUM2LONG(step);
+    else if (FIXNUM_P(step)) {
+	unit = NUM2LONG(step);
+    }
+    else {
+	VALUE tmp = rb_to_int(step);
+	unit = rb_cmpint(tmp, step, INT2FIX(0));
+	step = tmp;
+    }
     if (unit < 0) {
 	rb_raise(rb_eArgError, "step can't be negative");
-    } 
+    }
     if (unit == 0)
 	rb_raise(rb_eArgError, "step can't be 0");
-    if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
+    if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
 	long end = FIX2LONG(e);
 	long i;
 
@@ -322,14 +335,13 @@
 	VALUE tmp = rb_check_string_type(b);
 
 	if (!NIL_P(tmp)) {
-	    VALUE args[2];
-	    long iter[2];
+	    VALUE args[2], iter[2];
 
 	    b = tmp;
 	    args[0] = e;
 	    args[1] = EXCL(range) ? Qtrue : Qfalse;
-	    iter[0] = 1;
-	    iter[1] = unit;
+	    iter[0] = INT2FIX(1);
+	    iter[1] = step;
 	    rb_block_call(b, rb_intern("upto"), 2, args, step_i, (VALUE)iter);
 	}
 	else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
@@ -343,14 +355,14 @@
 	    }
 	}
 	else {
-	    long args[2];
+	    VALUE args[2];
 
 	    if (!rb_respond_to(b, id_succ)) {
 		rb_raise(rb_eTypeError, "can't iterate from %s",
 			 rb_obj_classname(b));
 	    }
-	    args[0] = 1;
-	    args[1] = unit;
+	    args[0] = INT2FIX(1);
+	    args[1] = step;
 	    range_each_func(range, step_i, b, e, args);
 	}
     }
@@ -866,8 +878,6 @@
 void
 Init_Range(void)
 {
-    VALUE members;
-
     id_cmp = rb_intern("<=>");
     id_succ = rb_intern("succ");
     id_beg = rb_intern("begin");
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog	(revision 14106)
+++ ruby_1_8/ChangeLog	(revision 14107)
@@ -1,3 +1,8 @@
+Wed Dec  5 15:15:21 2007  Nobuyoshi Nakada  <nobu@r...>
+
+	* range.c (step_i, range_step): support non-fixnum steps.
+	  [ruby-talk:282100]
+
 Tue Dec  4 11:23:50 2007  Nobuyoshi Nakada  <nobu@r...>
 
 	* bignum.c (rb_cstr_to_inum): trailing spaces may exist at sqeezing
Index: ruby_1_8/version.h
===================================================================
--- ruby_1_8/version.h	(revision 14106)
+++ ruby_1_8/version.h	(revision 14107)
@@ -1,7 +1,7 @@
 #define RUBY_VERSION "1.8.6"
-#define RUBY_RELEASE_DATE "2007-12-04"
+#define RUBY_RELEASE_DATE "2007-12-05"
 #define RUBY_VERSION_CODE 186
-#define RUBY_RELEASE_CODE 20071204
+#define RUBY_RELEASE_CODE 20071205
 #define RUBY_PATCHLEVEL 5000
 
 #define RUBY_VERSION_MAJOR 1
@@ -9,7 +9,7 @@
 #define RUBY_VERSION_TEENY 6
 #define RUBY_RELEASE_YEAR 2007
 #define RUBY_RELEASE_MONTH 12
-#define RUBY_RELEASE_DAY 4
+#define RUBY_RELEASE_DAY 5
 
 #ifdef RUBY_EXTERN
 RUBY_EXTERN const char ruby_version[];
Index: ruby_1_8/range.c
===================================================================
--- ruby_1_8/range.c	(revision 14106)
+++ ruby_1_8/range.c	(revision 14107)
@@ -254,12 +254,20 @@
 }
 
 static VALUE
-step_i(i, iter)
+step_i(i, arg)
     VALUE i;
-    long *iter;
+    VALUE arg;
 {
-    iter[0]--;
-    if (iter[0] == 0) {
+    VALUE *iter = (VALUE *)arg;
+
+    if (FIXNUM_P(iter[0])) {
+	iter[0] -= INT2FIX(1) & ~FIXNUM_FLAG;
+    }
+    else {
+	VALUE one = INT2FIX(1);
+	iter[0] = rb_funcall(iter[0], '-', 1, &one);
+    }
+    if (iter[0] == INT2FIX(0)) {
 	rb_yield(i);
 	iter[0] = iter[1];
     }
@@ -307,13 +315,22 @@
     e = rb_ivar_get(range, id_end);
     if (rb_scan_args(argc, argv, "01", &step) == 0) {
 	step = INT2FIX(1);
+	unit = 1;
     }
-
-    unit = NUM2LONG(step);
+    else if (FIXNUM_P(step)) {
+	unit = NUM2LONG(step);
+    }
+    else {
+	VALUE tmp = rb_to_int(step);
+	unit = rb_cmpint(tmp, step, INT2FIX(0));
+	step = tmp;
+    }
     if (unit < 0) {
 	rb_raise(rb_eArgError, "step can't be negative");
-    } 
-    if (FIXNUM_P(b) && FIXNUM_P(e)) { /* fixnums are special */
+    }
+    if (unit == 0)
+	rb_raise(rb_eArgError, "step can't be 0");
+    if (FIXNUM_P(b) && FIXNUM_P(e) && FIXNUM_P(step)) { /* fixnums are special */
 	long end = FIX2LONG(e);
 	long i;
 
@@ -330,36 +347,32 @@
 	VALUE tmp = rb_check_string_type(b);
 
 	if (!NIL_P(tmp)) {
-	    VALUE args[5];
-	    long iter[2];
+	    VALUE args[5], iter[2];
 
 	    b = tmp;
-	    if (unit == 0) rb_raise(rb_eArgError, "step can't be 0");
 	    args[0] = b; args[1] = e; args[2] = range;
-	    iter[0] = 1; iter[1] = unit;
+	    iter[0] = INT2FIX(1); iter[1] = step;
 	    rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i,
 			(VALUE)iter);
 	}
 	else if (rb_obj_is_kind_of(b, rb_cNumeric)) {
 	    ID c = rb_intern(EXCL(range) ? "<" : "<=");
 
-	    if (rb_equal(step, INT2FIX(0))) rb_raise(rb_eArgError, "step can't be 0");
 	    while (RTEST(rb_funcall(b, c, 1, e))) {
 		rb_yield(b);
 		b = rb_funcall(b, '+', 1, step);
 	    }
 	}
 	else {
-	    long args[2];
+	    VALUE args[2];
 
-	    if (unit == 0) rb_raise(rb_eArgError, "step can't be 0");
 	    if (!rb_respond_to(b, id_succ)) {
 		rb_raise(rb_eTypeError, "can't iterate from %s",
 			 rb_obj_classname(b));
 	    }
 	
-	    args[0] = 1;
-	    args[1] = unit;
+	    args[0] = INT2FIX(1);
+	    args[1] = step;
 	    range_each_func(range, step_i, b, e, args);
 	}
     }

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml

[前][次][番号順一覧][スレッド一覧]