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 /random.c | |
parent | 89339af9c19c28eaa9e2814fb75aa09768971f0e (diff) | |
download | ruby-2f6c0e3be38b057239eb044426c152ac5633c88f.tar.gz |
* 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 'random.c')
-rw-r--r-- | random.c | 35 |
1 files changed, 30 insertions, 5 deletions
@@ -321,6 +321,7 @@ int_pair_to_real_inclusive(unsigned int a, unsigned int b) VALUE rb_cRandom; #define id_minus '-' #define id_plus '+' +static ID id_rand, id_bytes; /* :nodoc: */ static void @@ -359,6 +360,13 @@ get_rnd(VALUE obj) return ptr; } +static rb_random_t * +try_get_rnd(VALUE obj) +{ + if (!rb_typeddata_is_kind_of(obj, &random_data_type)) return NULL; + return DATA_PTR(obj); +} + /* :nodoc: */ static VALUE random_alloc(VALUE klass) @@ -869,14 +877,22 @@ rb_rand_internal(unsigned long i) unsigned int rb_random_int32(VALUE obj) { - rb_random_t *rnd = get_rnd(obj); + rb_random_t *rnd = try_get_rnd(obj); + if (!rnd) { + VALUE lim = ULONG2NUM(0xffffffff); + return NUM2ULONG(rb_funcall2(obj, id_rand, 1, &lim)); + } return genrand_int32(&rnd->mt); } double rb_random_real(VALUE obj) { - rb_random_t *rnd = get_rnd(obj); + rb_random_t *rnd = try_get_rnd(obj); + if (!rnd) { + VALUE v = rb_funcall2(obj, id_rand, 0, 0); + return NUM2DBL(v); + } return genrand_real(&rnd->mt); } @@ -895,11 +911,17 @@ random_bytes(VALUE obj, VALUE len) VALUE rb_random_bytes(VALUE obj, long n) { - rb_random_t *rnd = get_rnd(obj); - VALUE bytes = rb_str_new(0, n); - char *ptr = RSTRING_PTR(bytes); + rb_random_t *rnd = try_get_rnd(obj); + VALUE bytes; + char *ptr; unsigned int r, i; + if (!rnd) { + VALUE len = LONG2NUM(n); + return rb_funcall2(obj, id_bytes, 1, &len); + } + bytes = rb_str_new(0, n); + ptr = RSTRING_PTR(bytes); for (; n >= SIZEOF_INT32; n -= SIZEOF_INT32) { r = genrand_int32(&rnd->mt); i = SIZEOF_INT32; @@ -1245,4 +1267,7 @@ Init_Random(void) rb_define_singleton_method(rb_cRandom, "new_seed", random_seed, 0); rb_define_private_method(CLASS_OF(rb_cRandom), "state", random_s_state, 0); rb_define_private_method(CLASS_OF(rb_cRandom), "left", random_s_left, 0); + + id_rand = rb_intern("rand"); + id_bytes = rb_intern("bytes"); } |