diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-08-23 22:07:39 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2010-08-23 22:07:39 +0000 |
commit | 2f6c0e3be38b057239eb044426c152ac5633c88f (patch) | |
tree | 694c7ce5c54b257050d1417974c970ec6cfd7651 /array.c | |
parent | 89339af9c19c28eaa9e2814fb75aa09768971f0e (diff) |
* array.c (rb_ary_shuffle_bang, rb_ary_sample): add optional
argument random. [ruby-dev:41923] [EXPERIMENTAL]
* random.c (rb_random_{int32,real,bytes}): fallback to normal
method invocation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@29083 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r-- | array.c | 45 |
1 files changed, 33 insertions, 12 deletions
@@ -3730,22 +3730,30 @@ rb_ary_flatten(int argc, VALUE *argv, VALUE ary) return result; } -#define RAND_UPTO(max) (long)(rb_genrand_real()*(max)) +#define OPTHASH_GIVEN_P(opts) \ + (argc > 0 && !NIL_P(opts = rb_check_hash_type(argv[argc-1])) && (--argc, 1)) +static VALUE sym_random; + +#define RAND_UPTO(max) (long)(rb_random_real(randgen)*(max)) /* * call-seq: - * ary.shuffle! -> ary + * ary.shuffle! -> ary + * ary.shuffle!(random: rng) -> ary * * Shuffles elements in +self+ in place. + * If +rng+ is given, it will be used as the random number generator. */ - static VALUE -rb_ary_shuffle_bang(VALUE ary) +rb_ary_shuffle_bang(int argc, VALUE *argv, VALUE ary) { - VALUE *ptr; + VALUE *ptr, opts, randgen = Qnil; long i = RARRAY_LEN(ary); + if (OPTHASH_GIVEN_P(opts)) { + randgen = rb_hash_lookup2(opts, sym_random, randgen); + } rb_ary_modify(ary); ptr = RARRAY_PTR(ary); while (i) { @@ -3760,27 +3768,34 @@ rb_ary_shuffle_bang(VALUE ary) /* * call-seq: - * ary.shuffle -> new_ary + * ary.shuffle -> new_ary + * ary.shuffle(random: rng) -> new_ary * * Returns a new array with elements of this array shuffled. * * a = [ 1, 2, 3 ] #=> [1, 2, 3] * a.shuffle #=> [2, 3, 1] + * + * If +rng+ is given, it will be used as the random number generator. + * + * a.shuffle(Random.new(1)) #=> [1, 3, 2] */ static VALUE -rb_ary_shuffle(VALUE ary) +rb_ary_shuffle(int argc, VALUE *argv, VALUE ary) { ary = rb_ary_dup(ary); - rb_ary_shuffle_bang(ary); + rb_ary_shuffle_bang(argc, argv, ary); return ary; } /* * call-seq: - * ary.sample -> obj - * ary.sample(n) -> new_ary + * ary.sample -> obj + * ary.sample(random: rng) -> obj + * ary.sample(n) -> new_ary + * ary.sample(n, random: rng) -> new_ary * * Choose a random element or +n+ random elements from the array. The elements * are chosen by using random and unique indices into the array in order to @@ -3788,6 +3803,7 @@ rb_ary_shuffle(VALUE ary) * contained duplicate elements. If the array is empty the first form returns * <code>nil</code> and the second form returns an empty array. * + * If +rng+ is given, it will be used as the random number generator. */ @@ -3795,9 +3811,13 @@ static VALUE rb_ary_sample(int argc, VALUE *argv, VALUE ary) { VALUE nv, result, *ptr; + VALUE opts, randgen = Qnil; long n, len, i, j, k, idx[10]; len = RARRAY_LEN(ary); + if (OPTHASH_GIVEN_P(opts)) { + randgen = rb_hash_lookup2(opts, sym_random, randgen); + } if (argc == 0) { if (len == 0) return Qnil; i = len == 1 ? 0 : RAND_UPTO(len); @@ -4595,8 +4615,8 @@ Init_Array(void) rb_define_method(rb_cArray, "flatten", rb_ary_flatten, -1); rb_define_method(rb_cArray, "flatten!", rb_ary_flatten_bang, -1); 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, "shuffle!", rb_ary_shuffle_bang, -1); + rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, -1); 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); @@ -4611,4 +4631,5 @@ Init_Array(void) rb_define_method(rb_cArray, "drop_while", rb_ary_drop_while, 0); id_cmp = rb_intern("<=>"); + sym_random = ID2SYM(rb_intern("random")); } |