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

ruby-changes:6991

From: matz <ko1@a...>
Date: Tue, 12 Aug 2008 14:09:05 +0900 (JST)
Subject: [ruby-changes:6991] Ruby:r18509 (ruby_1_8): * array.c (rb_ary_sample): rename #choice to #sample. in

matz	2008-08-12 14:08:52 +0900 (Tue, 12 Aug 2008)

  New Revision: 18509

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

  Log:
    * array.c (rb_ary_sample): rename #choice to #sample.  in
      addition, sample takes optional argument, a la #first.
    
    * random.c (Init_Random): always initialize seed.

  Modified files:
    branches/ruby_1_8/ChangeLog
    branches/ruby_1_8/array.c
    branches/ruby_1_8/random.c

Index: ruby_1_8/array.c
===================================================================
--- ruby_1_8/array.c	(revision 18508)
+++ ruby_1_8/array.c	(revision 18509)
@@ -3301,22 +3301,51 @@
 
 /*
  *  call-seq:
- *     array.choice        -> obj
+ *     array.sample        -> obj
+ *     array.sample(n)     -> an_array
  *  
- *  Choose a random element from an array.
+ *  Choose a random element, or the random +n+ elements, fron the array.
+ *  If the array is empty, the first form returns <code>nil</code>, and the
+ *  second form returns an empty array.
+ *  
  */
 
 
 static VALUE
-rb_ary_choice(ary)
+rb_ary_sample(argc, argv, ary)
+    int argc;
+    VALUE *argv;
     VALUE ary;
 {
-    long i, j;
+    VALUE nv, result;
+    int n, len, i, j;
 
-    i = RARRAY(ary)->len;
-    if (i == 0) return Qnil;
-    j = rb_genrand_real()*i;
-    return RARRAY(ary)->ptr[j];
+    len = RARRAY_LEN(ary); 
+    if (argc == 0) {
+	if (len == 0) return Qnil;
+	i = rb_genrand_real()*len;
+	return RARRAY_PTR(ary)[i];
+    }
+    rb_scan_args(argc, argv, "1", &nv);
+    if (len == 0) return rb_ary_new2(0);
+    n = NUM2INT(nv);
+    result = rb_ary_new2(n);
+    for (i=0; i<n; i++) {
+      retry:
+	j = rb_genrand_real()*len;
+	nv = LONG2NUM(j);
+	for (j=0; j<i; j++) {
+	    if (RARRAY_PTR(result)[j] == nv)
+		goto retry;
+	}
+	RARRAY_PTR(result)[i] = nv;
+	RARRAY(result)->len = i+1;
+    }
+    for (i=0; i<n; i++) {
+	nv = RARRAY_PTR(result)[i];
+	RARRAY_PTR(result)[i] = RARRAY_PTR(ary)[NUM2LONG(nv)];
+    }
+    return result;
 }
 
 
@@ -3852,7 +3881,7 @@
     rb_define_method(rb_cArray, "count", rb_ary_count, -1);
     rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
     rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
-    rb_define_method(rb_cArray, "choice", rb_ary_choice, 0);
+    rb_define_method(rb_cArray, "sample", rb_ary_sample, -1);
     rb_define_method(rb_cArray, "cycle", rb_ary_cycle, -1);
     rb_define_method(rb_cArray, "permutation", rb_ary_permutation, -1);
     rb_define_method(rb_cArray, "combination", rb_ary_combination, 1);
Index: ruby_1_8/ChangeLog
===================================================================
--- ruby_1_8/ChangeLog	(revision 18508)
+++ ruby_1_8/ChangeLog	(revision 18509)
@@ -4,6 +4,13 @@
 	  regexp to only pick definition lines properly.  `module_funtion'
 	  is not a definition of a module named `_function'.
 
+Tue Aug 12 11:19:32 2008  Yukihiro Matsumoto  <matz@r...>
+
+	* array.c (rb_ary_sample): rename #choice to #sample.  in
+	  addition, sample takes optional argument, a la #first.
+
+	* random.c (Init_Random): always initialize seed.
+
 Mon Aug 11 14:39:46 2008  Yukihiro Matsumoto  <matz@r...>
 
 	* class.c (clone_method): should copy cbase in cref as well.
Index: ruby_1_8/random.c
===================================================================
--- ruby_1_8/random.c	(revision 18508)
+++ ruby_1_8/random.c	(revision 18509)
@@ -189,7 +189,6 @@
 #include <fcntl.h>
 #endif
 
-static int first = 1;
 static VALUE saved_seed = INT2FIX(0);
 
 static VALUE
@@ -245,7 +244,6 @@
             len--;
         init_by_array(buf, len);
     }
-    first = 0;
     old = saved_seed;
     saved_seed = seed;
     free(buf);
@@ -445,9 +443,6 @@
     long val, max;
 
     rb_scan_args(argc, argv, "01", &vmax);
-    if (first) {
-	rand_init(random_seed());
-    }
     switch (TYPE(vmax)) {
       case T_FLOAT:
 	if (RFLOAT(vmax)->value <= LONG_MAX && RFLOAT(vmax)->value >= LONG_MIN) {
@@ -498,6 +493,7 @@
 void
 Init_Random()
 {
+    rand_init(random_seed());
     rb_define_global_function("srand", rb_f_srand, -1);
     rb_define_global_function("rand", rb_f_rand, -1);
     rb_global_variable(&saved_seed);

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

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