[ruby-list:502] Re: bugreports(Enum#find/find_all, ruby-mode.el) and Requests

From: matz@... (Yukihiro Matsumoto)
Date: 1996-09-11 10:12:07 UTC
List: ruby-list #502
とりあえずパッチを流しておきます.

In message "[ruby-list:499] Re: bugreports(Enum#find/find_all, ruby-mode.el) and Requests"
    on 96/09/11, Yukihiro Matsumoto <matz@caelum.co.jp> writes:

|確かに.Bignumの引き算は全般におかしいようです.これはちょっ
|と時間がかかりそうです(根が深い).

--- bignum.c~	Wed Sep  4 17:16:25 1996
+++ bignum.c	Wed Sep 11 18:39:57 1996
@@ -512,13 +512,22 @@
 big_minus(x, y)
     VALUE x, y;
 {
+    VALUE cmp;
+
     if (FIXNUM_P(y)) y = int2big(FIX2INT(y));
     else {
 	Check_Type(y, T_BIGNUM);
     }
-    x = bigadd(x, y, 0);
-
-    return x;
+    cmp = big_cmp(x, y);
+    if (FIX2INT(cmp) == 0) {
+	return INT2FIX(0);
+    }
+    if (FIX2INT(cmp) > 0) {
+	x = bigadd(y, x, 0);
+	if (FIXNUM_P(x)) return int2inum(-FIX2INT(x));
+	return big_neg(x);
+    }
+    return bigadd(x, y, 0);
 }
 
 VALUE
@@ -1098,18 +1107,24 @@
 {
     struct RBignum *v;
     int len;
-    int i;
 
-    len = RAND() % max->len + 1;
+    len = max->len;
     v = RBIGNUM(bignew(len,1));
-    for (i=0; i<v->len; i++) {
-	BDIGITS(v)[i] = RAND();
+    while (len--) {
+	BDIGITS(v)[len] = RAND();
     }
 
     return big_mod(v, max);
 #undef RAND
 }
 
+static VALUE
+big_size(big)
+    struct RBignum *big;
+{
+    return INT2FIX(big->len*2);
+}
+
 void
 Init_Bignum()
 {
@@ -1138,5 +1153,6 @@
     rb_define_method(cBignum, "hash", big_hash, 0);
     rb_define_method(cBignum, "to_i", big_to_i, 0);
     rb_define_method(cBignum, "to_f", big_to_f, 0);
-    rb_define_method(cBignum, "abs_f", big_abs, 0);
+    rb_define_method(cBignum, "abs", big_abs, 0);
+    rb_define_method(cBignum, "size", big_size, 0);
 }


||>|1. Enumerable#find/find_all

||で, proc{}はない時に実行されるブロック. デフォルトの動作はnilを帰すと
||いうのはどうですか?

--- enum.c~	Wed Sep 11 01:25:31 1996
+++ enum.c	Wed Sep 11 18:52:44 1996
@@ -58,26 +58,40 @@
     }
 }
 
+struct find_arg {
+    int found;
+    VALUE val;
+};
+    
 static void
-find_i(i, foundp)
+find_i(i, arg)
     VALUE i;
-    int *foundp;
+    struct find_arg *arg;
 {
     if (RTEST(rb_yield(i))) {
-	*foundp = TRUE;
+	arg->found = TRUE;
+	arg->val = i;
 	rb_break();
     }
 }
 
 static VALUE
-enum_find(obj)
+enum_find(argc, argv, obj)
+    int argc;
+    VALUE argv;
     VALUE obj;
 {
-    int enum_found;
+    struct find_arg arg;
+    VALUE if_none;
 
-    enum_found = FALSE;
-    rb_iterate(rb_each, obj, find_i, &enum_found);
-    return enum_found;
+    rb_scan_args(argc, argv, "01", &if_none);
+    arg.found = FALSE;
+    rb_iterate(rb_each, obj, find_i, &arg);
+    if (arg.found) {
+	return arg.val;
+    }
+    if (NIL_P(if_none)) return Qnil;
+    rb_eval_cmd(if_none, Qnil);
 }
 
 static void

In This Thread

Prev Next