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

ruby-changes:5176

From: knu <ko1@a...>
Date: Wed, 28 May 2008 17:53:09 +0900 (JST)
Subject: [ruby-changes:5176] Ruby:r16671 (ruby_1_8_7): Merge from ruby_1_8.

knu	2008-05-28 17:52:57 +0900 (Wed, 28 May 2008)

  New Revision: 16671

  Modified files:
    branches/ruby_1_8_7/ChangeLog
    branches/ruby_1_8_7/NEWS
    branches/ruby_1_8_7/range.c
    branches/ruby_1_8_7/string.c

  Log:
    Merge from ruby_1_8.

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/ChangeLog?r1=16671&r2=16670&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/NEWS?r1=16671&r2=16670&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/string.c?r1=16671&r2=16670&diff_format=u
  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/branches/ruby_1_8_7/range.c?r1=16671&r2=16670&diff_format=u

Index: ruby_1_8_7/NEWS
===================================================================
--- ruby_1_8_7/NEWS	(revision 16670)
+++ ruby_1_8_7/NEWS	(revision 16671)
@@ -246,6 +246,11 @@
 
     Return an enumerator if no block is given.
 
+  * String#upto
+
+    An optional second argument is added to specify if the last value
+    should be included.
+
   * StopIteration
 
     New exception class that causes Kernel#loop to stop iteration when
Index: ruby_1_8_7/ChangeLog
===================================================================
--- ruby_1_8_7/ChangeLog	(revision 16670)
+++ ruby_1_8_7/ChangeLog	(revision 16671)
@@ -1,3 +1,13 @@
+Wed May 28 17:48:28 2008  Akinori MUSHA  <knu@i...>
+
+	* range.c (range_step): Fix brokenness when a non-integer numeric
+	  value is specified as step. [rubyspec]
+	  (range_step): Make use of String#step internally if a string (or
+	  string-alike) range is given.
+
+	* string.c (rb_str_upto_m, Init_String): Add an optional second
+	  argument to specify if the last value should be included.
+
 Wed May 28 16:53:39 2008  Akinori MUSHA  <knu@i...>
 
 	* array.c (rb_ary_slice_bang): Call rb_ary_modify_check() at the
Index: ruby_1_8_7/string.c
===================================================================
--- ruby_1_8_7/string.c	(revision 16670)
+++ ruby_1_8_7/string.c	(revision 16671)
@@ -1492,12 +1492,13 @@
 
 /*
  *  call-seq:
- *     str.upto(other_str) {|s| block }   => str
+ *     str.upto(other_str, exclusive=false) {|s| block }   => str
  *  
  *  Iterates through successive values, starting at <i>str</i> and
  *  ending at <i>other_str</i> inclusive, passing each value in turn to
  *  the block. The <code>String#succ</code> method is used to generate
- *  each value.
+ *  each value.  If optional second argument exclusive is omitted or is <code>false</code>,
+ *  the last value will be included; otherwise it will be excluded.
  *     
  *     "a8".upto("b6") {|s| print s, ' ' }
  *     for s in "a8".."b6"
@@ -1511,10 +1512,15 @@
  */
 
 static VALUE
-rb_str_upto_m(beg, end)
-    VALUE beg, end;
+rb_str_upto_m(argc, argv, beg)
+    int argc;
+    VALUE argv, beg;
 {
-    return rb_str_upto(beg, end, Qfalse);
+    VALUE end, exclusive;
+
+    rb_scan_args(argc, argv, "11", &end, &exclusive);
+
+    return rb_str_upto(beg, end, RTEST(exclusive));
 }
 
 static VALUE
@@ -4929,7 +4935,7 @@
     rb_define_method(rb_cString, "succ!", rb_str_succ_bang, 0);
     rb_define_method(rb_cString, "next", rb_str_succ, 0);
     rb_define_method(rb_cString, "next!", rb_str_succ_bang, 0);
-    rb_define_method(rb_cString, "upto", rb_str_upto_m, 1);
+    rb_define_method(rb_cString, "upto", rb_str_upto_m, -1);
     rb_define_method(rb_cString, "index", rb_str_index_m, -1);
     rb_define_method(rb_cString, "rindex", rb_str_rindex_m, -1);
     rb_define_method(rb_cString, "replace", rb_str_replace, 1);
Index: ruby_1_8_7/range.c
===================================================================
--- ruby_1_8_7/range.c	(revision 16670)
+++ ruby_1_8_7/range.c	(revision 16671)
@@ -278,7 +278,7 @@
  *     rng.step(n=1) {| obj | block }    => rng
  *  
  *  Iterates over <i>rng</i>, passing each <i>n</i>th element to the block. If
- *  the range contains numbers or strings, natural ordering is used.  Otherwise
+ *  the range contains numbers, <i>n</i> is added for each iteration.  Otherwise
  *  <code>step</code> invokes <code>succ</code> to iterate through range
  *  elements. The following code uses class <code>Xs</code>, which is defined
  *  in the class-level documentation.
@@ -308,7 +308,6 @@
     VALUE range;
 {
     VALUE b, e, step, tmp;
-    long unit;
 
     RETURN_ENUMERATOR(range, argc, argv);
 
@@ -316,49 +315,56 @@
     e = rb_ivar_get(range, id_end);
     if (argc == 0) {
 	step = INT2FIX(1);
-	unit = 1;
     }
     else {
 	rb_scan_args(argc, argv, "01", &step);
-	tmp = rb_check_to_integer(step, "to_int");
-	if (!NIL_P(tmp)) {
-	    step = tmp;
-	    unit = NUM2LONG(step);
+	if (!rb_obj_is_kind_of(step, rb_cNumeric)) {
+	    step = rb_to_int(step);
 	}
-	else {
-	    tmp = rb_funcall(rb_funcall(b, '+', 1, step), '-', 1, b);
-	    unit = rb_cmpint(tmp, step, INT2FIX(0));
+	if (rb_funcall(step, '<', 1, INT2FIX(0))) {
+	    rb_raise(rb_eArgError, "step can't be negative");
 	}
+	else if (!rb_funcall(step, '>', 1, INT2FIX(0))) {
+	    rb_raise(rb_eArgError, "step can't be 0");
+	}
     }
-    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) && FIXNUM_P(step)) { /* fixnums are special */
 	long end = FIX2LONG(e);
-	long i;
+	long i, unit = FIX2LONG(step);
 
-	if (unit == 0) rb_raise(rb_eArgError, "step can't be 0");
-	if (!EXCL(range)) end += 1;
+	if (!EXCL(range))
+	    end += 1;
 	i = FIX2LONG(b);	
 	while (i < end) {
 	    rb_yield(LONG2NUM(i));
 	    if (i + unit < i) break;
 	    i += unit;
 	}
+
     }
+    else if (rb_obj_is_kind_of(b, rb_cNumeric) ||
+	     !NIL_P(rb_check_to_integer(b, "to_int")) ||
+	     !NIL_P(rb_check_to_integer(e, "to_int"))) {
+	ID op = EXCL(range) ? '<' : rb_intern("<=");
+
+	while (RTEST(rb_funcall(b, op, 1, e))) {
+	    rb_yield(b);
+	    b = rb_funcall(b, '+', 1, step);
+	}
+    }
     else {
-	VALUE tmp = rb_check_string_type(b);
+	tmp = rb_check_string_type(b);
 
 	if (!NIL_P(tmp)) {
 	    VALUE args[5], iter[2];
 
 	    b = tmp;
-	    args[0] = b; args[1] = e; args[2] = range;
-	    iter[0] = INT2FIX(1); iter[1] = step;
-	    rb_iterate((VALUE(*)_((VALUE)))str_step, (VALUE)args, step_i,
-			(VALUE)iter);
+	    args[0] = e;
+	    args[1] = EXCL(range) ? Qtrue : Qfalse;
+	    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) ||
 		 !NIL_P(rb_check_to_integer(b, "to_int")) ||
@@ -377,7 +383,6 @@
 		rb_raise(rb_eTypeError, "can't iterate from %s",
 			 rb_obj_classname(b));
 	    }
-	
 	    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/

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