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/