[#40130] Ruby/Tk の講習会 — Hidetoshi NAGAI <nagai@...>

永井@知能.九工大です.

12 messages 2004/10/25

[ruby-list:40105] Re: require 中に例外が発生したときの対処について

From: nobu@...
Date: 2004-10-16 10:06:44 UTC
List: ruby-list #40105
なかだです。

At Wed, 13 Oct 2004 16:11:32 +0900,
Yukihiro Matsumoto wrote in [ruby-list:40086]:
> | あるファイルを require 中に、たとえばその先で require する
> |ものがインストールされていなかった場合など、例外が発生します。
> |そのとき、$" には、最初に require したファイルが記録されます
> |ので、次に require しても、読み込みを行いません。たとえば、
> |例外発生要因を取り除いた後にもう一度 require するような場合、
> |これに気づかずにはまるかもしれません(というか、はまった)。
> 
> うーむ、本当は
> 
>   provideはrequireが成功してから
> 
> という風に実装すべきなんですが、これをするとrequire中にふた
> たび同じライブラリをrequireしたときに無限ループに陥ると言う
> 問題が生じます。おそらく、現在require中のものとすでにrequire
> したものの両方のリストを見ればよいのでしょうね。

loading_tblを使えばすぐできますが、失敗したrequireまでの部分は
二度実行されることになってしまいます。どっちがいいんでしょうねぇ。


Index: eval.c
===================================================================
RCS file: /cvs/ruby/src/ruby/eval.c,v
retrieving revision 1.708
diff -U2 -p -d -r1.708 eval.c
--- eval.c	15 Oct 2004 03:53:23 -0000	1.708
+++ eval.c	16 Oct 2004 08:30:35 -0000
@@ -6625,5 +6625,5 @@ rb_provide(feature)
 }
 
-static void
+static int
 load_wait(ftptr)
     char *ftptr;
@@ -6631,11 +6631,12 @@ load_wait(ftptr)
     st_data_t th;
 
-    if (!loading_tbl) return;
-    if (!st_lookup(loading_tbl, (st_data_t)ftptr, &th)) return;
-    if ((rb_thread_t)th == curr_thread) return;
+    if (!loading_tbl) return Qfalse;
+    if (!st_lookup(loading_tbl, (st_data_t)ftptr, &th)) return Qfalse;
+    if ((rb_thread_t)th == curr_thread) return Qtrue;
     do {
 	CHECK_INTS;
 	rb_thread_schedule();
     } while (st_lookup(loading_tbl, (st_data_t)ftptr, &th));
+    return Qtrue;
 }
 
@@ -6762,11 +6763,9 @@ rb_require_safe(fname, safe)
 	found = search_required(fname, &feature, &path);
 	if (found) {
-	    if (!path) {
-		load_wait(RSTRING(feature)->ptr);
+	    if (!path || load_wait(RSTRING(feature)->ptr)) {
 		result = Qfalse;
 	    }
 	    else {
 		ruby_safe_level = 0;
-		rb_provide_feature(feature);
 		switch (found) {
 		  case 'r':
@@ -6795,4 +6794,5 @@ rb_require_safe(fname, safe)
 		    break;
 		}
+		rb_provide_feature(feature);
 		result = Qtrue;
 	    }


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread