summaryrefslogtreecommitdiff
path: root/random.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-08-23 22:07:39 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-08-23 22:07:39 +0000
commit2f6c0e3be38b057239eb044426c152ac5633c88f (patch)
tree694c7ce5c54b257050d1417974c970ec6cfd7651 /random.c
parent89339af9c19c28eaa9e2814fb75aa09768971f0e (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 'random.c')
-rw-r--r--random.c35
1 files changed, 30 insertions, 5 deletions
diff --git a/random.c b/random.c
index ef0de1f750..a89fcb8ee9 100644
--- a/random.c
+++ b/random.c
@@ -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");
}