summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog13
-rw-r--r--array.c47
-rw-r--r--intern.h4
-rw-r--r--random.c10
4 files changed, 65 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index f71fb11809..b51fed5bdd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+Thu Aug 31 17:16:19 2006 Yukihiro Matsumoto <matz@ruby-lang.org>
+
+ * array.c (rb_ary_shuffle_bang): new method.
+
+ * array.c (rb_ary_shuffle): ditto.
+
+ * random.c (genrand_real): ditto.
+
+ * random.c (genrand_int32): export the function.
+
+ * random.c (Init_Random): initialize random seed at the
+ beginning.
+
Thu Aug 31 13:12:06 2006 why the lucky stiff <why@ruby-lang.org>
* eval.c (ruby_init): rename top_cref to ruby_top_cref and export,
diff --git a/array.c b/array.c
index 5bf0e9979d..0ffc9a6a75 100644
--- a/array.c
+++ b/array.c
@@ -1222,11 +1222,11 @@ rb_ary_join(VALUE ary, VALUE sep)
for (i=0; i<RARRAY(ary)->len; i++) {
tmp = rb_check_string_type(RARRAY(ary)->ptr[i]);
- len += NIL_P(tmp) ? 10 : RSTRING(tmp)->len;
+ len += NIL_P(tmp) ? 10 : RSTRING_LEN(tmp);
}
if (!NIL_P(sep)) {
StringValue(sep);
- len += RSTRING(sep)->len * (RARRAY(ary)->len - 1);
+ len += RSTRING_LEN(sep) * (RARRAY(ary)->len - 1);
}
result = rb_str_buf_new(len);
for (i=0; i<RARRAY(ary)->len; i++) {
@@ -2799,6 +2799,47 @@ rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
return ary;
}
+/*
+ * call-seq:
+ * array.shuffle! -> array or
+ *
+ * Shuffles elements in _self_ in place.
+ */
+
+
+static VALUE
+rb_ary_shuffle_bang(VALUE ary)
+{
+ long i = RARRAY(ary)->len;
+
+ while (i) {
+ long j = genrand_real()*i;
+ VALUE tmp = RARRAY(ary)->ptr[--i];
+ RARRAY(ary)->ptr[i] = RARRAY(ary)->ptr[j];
+ RARRAY(ary)->ptr[j] = tmp;
+ }
+ return ary;
+}
+
+
+/*
+ * call-seq:
+ * array.shuffle -> an_array
+ *
+ * Returns a new array that with elements of this array shuffled.
+ *
+ * s = [ 1, 2, 3 ] #=> [1, 2, 3]
+ * a.shuffle #=> [1, 2, 3]
+ */
+
+static VALUE
+rb_ary_shuffle(VALUE ary)
+{
+ ary = rb_ary_dup(ary);
+ rb_ary_shuffle_bang(ary);
+ return ary;
+}
+
/* Arrays are ordered, integer-indexed collections of any object.
* Array indexing starts at 0, as in C or Java. A negative index is
@@ -2893,6 +2934,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, "nitems", rb_ary_nitems, 0);
+ rb_define_method(rb_cArray, "shuffle!", rb_ary_shuffle_bang, 0);
+ rb_define_method(rb_cArray, "shuffle", rb_ary_shuffle, 0);
id_cmp = rb_intern("<=>");
}
diff --git a/intern.h b/intern.h
index 5a941b6627..e2fea30882 100644
--- a/intern.h
+++ b/intern.h
@@ -426,6 +426,9 @@ VALUE rb_detach_process(int);
VALUE rb_range_new(VALUE, VALUE, int);
VALUE rb_range_beg_len(VALUE, long*, long*, long, int);
VALUE rb_length_by_each(VALUE);
+/* random.c */
+unsigned long genrand_int32(void);
+double genrand_real(void);
/* re.c */
int rb_memcmp(const void*,const void*,long);
int rb_memcicmp(const void*,const void*,long);
@@ -497,6 +500,7 @@ VALUE rb_str_times(VALUE, VALUE);
VALUE rb_str_substr(VALUE, long, long);
void rb_str_modify(VALUE);
VALUE rb_str_freeze(VALUE);
+void rb_str_set_len(VALUE, long);
VALUE rb_str_resize(VALUE, long);
VALUE rb_str_cat(VALUE, const char*, long);
VALUE rb_str_cat2(VALUE, const char*);
diff --git a/random.c b/random.c
index fc3af2638b..2d335d13f8 100644
--- a/random.c
+++ b/random.c
@@ -145,7 +145,7 @@ next_state(void)
}
/* generates a random number on [0,0xffffffff]-interval */
-static unsigned long
+unsigned long
genrand_int32(void)
{
unsigned long y;
@@ -163,7 +163,7 @@ genrand_int32(void)
}
/* generates a random number on [0,1) with 53-bit resolution*/
-static double
+double
genrand_real(void)
{
unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6;
@@ -188,7 +188,6 @@ genrand_real(void)
#include <fcntl.h>
#endif
-static int first = 1;
static VALUE saved_seed = INT2FIX(0);
static VALUE
@@ -243,7 +242,6 @@ rand_init(VALUE vseed)
len--;
init_by_array(buf, len);
}
- first = 0;
old = saved_seed;
saved_seed = seed;
free(buf);
@@ -437,9 +435,6 @@ rb_f_rand(int argc, VALUE *argv, VALUE 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) {
@@ -489,6 +484,7 @@ rb_f_rand(int argc, VALUE *argv, VALUE obj)
void
Init_Random(void)
{
+ 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);