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

ruby-changes:15313

From: marcandre <ko1@a...>
Date: Sat, 3 Apr 2010 06:56:56 +0900 (JST)
Subject: [ruby-changes:15313] Ruby:r27200 (trunk): * array.c (rb_ary_product): Accept a block

marcandre	2010-04-03 06:56:34 +0900 (Sat, 03 Apr 2010)

  New Revision: 27200

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=27200

  Log:
    * array.c (rb_ary_product): Accept a block [ruby-core:29045]

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/array.c

Index: array.c
===================================================================
--- array.c	(revision 27199)
+++ array.c	(revision 27200)
@@ -4052,12 +4052,16 @@
 
 /*
  *  call-seq:
- *     ary.product(other_ary, ...)
+ *     ary.product(other_ary, ...)                -> array
+ *     ary.product(other_ary, ...) { |p| block }  -> ary
  *
- *  Returns an array of all combinations of elements from all arrays.
+ *  Returns an array of all combinations of elements from all arrays,
  *  The length of the returned array is the product of the length
- *  of ary and the argument arrays
+ *  of ary and the argument arrays.
+ *  If given a block, <i>product</i> will yield all combinations
+ *  and return self instead.
  *
+ *
  *     [1,2,3].product([4,5])     # => [[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]
  *     [1,2].product([1,2])       # => [[1,1],[1,2],[2,1],[2,2]]
  *     [1,2].product([3,4],[5,6]) # => [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
@@ -4074,7 +4078,7 @@
     volatile VALUE t1 = tmpbuf(n, sizeof(int));
     VALUE *arrays = (VALUE*)RSTRING_PTR(t0); /* The arrays we're computing the product of */
     int *counters = (int*)RSTRING_PTR(t1); /* The current position in each one */
-    VALUE result;      /* The array we'll be returning */
+    VALUE result = Qnil;      /* The array we'll be returning, when no block given */
     long i,j;
     long resultlen = 1;
 
@@ -4091,7 +4095,7 @@
     /* Compute the length of the result array; return [] if any is empty */
     for (i = 0; i < n; i++) {
 	long k = RARRAY_LEN(arrays[i]), l = resultlen;
-	if (k == 0) return rb_ary_new2(0);
+	if (k == 0) return rb_block_given_p() ? ary : rb_ary_new2(0);
 	resultlen *= k;
 	if (resultlen < k || resultlen < l || resultlen / k != l) {
 	    rb_raise(rb_eRangeError, "too big to product");
@@ -4099,7 +4103,9 @@
     }
 
     /* Otherwise, allocate and fill in an array of results */
-    result = rb_ary_new2(resultlen);
+    if (!rb_block_given_p()) {
+	result = rb_ary_new2(resultlen);
+    }
     for (i = 0; i < resultlen; i++) {
 	int m;
 	/* fill in one subarray */
@@ -4109,7 +4115,12 @@
 	}
 
 	/* put it on the result array */
-	rb_ary_push(result, subarray);
+	if(NIL_P(result)) {
+	    rb_yield(subarray);
+	}
+	else {
+	    rb_ary_push(result, subarray);
+	}
 
 	/*
 	 * Increment the last counter.  If it overflows, reset to 0
@@ -4126,7 +4137,7 @@
     tmpbuf_discard(t0);
     tmpbuf_discard(t1);
 
-    return result;
+    return NIL_P(result) ? ary : result;
 }
 
 /*
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 27199)
+++ ChangeLog	(revision 27200)
@@ -1,3 +1,7 @@
+Sat Apr  3 06:56:11 2010  Marc-Andre Lafortune  <ruby-core@m...>
+
+	* array.c (rb_ary_product): Accept a block [ruby-core:29045]
+
 Sat Apr  3 04:46:00 2010  Tanaka Akira  <akr@f...>
 
 	* tool/file2lastrev.rb (VCS#relative_to): path and @srcdir may have
Index: NEWS
===================================================================
--- NEWS	(revision 27199)
+++ NEWS	(revision 27200)
@@ -22,7 +22,7 @@
       * Array#sort_by!
 
     * extended methods:
-      * Array#{uniq,uniq!} can take a block.
+      * Array#{uniq,uniq!,product} can take a block.
 
   * Dir
     * new method:

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

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