diff --git a/ChangeLog b/ChangeLog index e8801cb90e..00d7fe3c59 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,6 +4,13 @@ Tue Aug 12 13:57:11 2008 Akinori MUSHA 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 + + * 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 * class.c (clone_method): should copy cbase in cref as well. diff --git a/array.c b/array.c index 7e8c12b683..9bd5e0bff3 100644 --- a/array.c +++ b/array.c @@ -3301,22 +3301,51 @@ rb_ary_shuffle(VALUE ary) /* * call-seq: - * array.choice -> obj + * array.sample -> obj + * array.sample(n) -> an_array + * + * Choose a random element, or the random +n+ elements, fron the array. + * If the array is empty, the first form returns nil, and the + * second form returns an empty array. * - * Choose a random element from an 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; ilen = i+1; + } + for (i=0; i #endif -static int first = 1; static VALUE saved_seed = INT2FIX(0); static VALUE @@ -245,7 +244,6 @@ rand_init(vseed) len--; init_by_array(buf, len); } - first = 0; old = saved_seed; saved_seed = seed; free(buf); @@ -445,9 +443,6 @@ rb_f_rand(argc, argv, obj) 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 @@ rb_f_rand(argc, argv, obj) 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);