[#18186] [req] Marshal — keiju@... (Keiju ISHITSUKA)

けいじゅ@日本ラショナルソフトウェアです.

14 messages 2002/09/05
[#18190] Re: [req] Marshal — matz@... (Yukihiro Matsumoto) 2002/09/05

まつもと ゆきひろです

[#18229] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...>

こんにちは、なかむら(う)です。

22 messages 2002/09/09
[#18230] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — nobu.nakada@... 2002/09/09

なかだです。

[#18231] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...> 2002/09/09

こんにちは、なかむら(う)です。

[#18232] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — nobu.nakada@... 2002/09/09

なかだです。

[#18233] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...> 2002/09/09

こんにちは、なかむら(う)です。

[#18234] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — WATANABE Hirofumi <eban@...> 2002/09/09

わたなべです。

[#18236] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...> 2002/09/09

こんにちは、なかむら(う)です。

[#18238] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — WATANABE Hirofumi <eban@...> 2002/09/09

わたなべです。

[#18241] Re: [ruby-cvs] rough/ext/stringio: * ruby-stringio.spec: 0.0.7, added changelog. — "U.Nakamura" <usa@...> 2002/09/09

こんにちは、なかむら(う)です。

[#18285] rubicon on EWS4800 — Koji Arai <JCA02266@...>

新井です。

59 messages 2002/09/13
[#18322] Re: rubicon on EWS4800 — Koji Arai <JCA02266@...> 2002/09/21

新井です。

[#18333] Re: rubicon on EWS4800 — kjana@...4lab.to (YANAGAWA Kazuhisa) 2002/09/21

In message <20020921.152641.11483667.JCA02266@nifty.ne.jp>

[#18336] Re: rubicon on EWS4800 — nobu.nakada@... 2002/09/21

なかだです。

[#18337] Re: rubicon on EWS4800 — Tanaka Akira <akr@...17n.org> 2002/09/21

In article <200209211605.g8LG52p04564@sharui.nakada.kanuma.tochigi.jp>,

[#18338] Re: rubicon on EWS4800 — nobu.nakada@... 2002/09/21

なかだです。

[#18341] Re: rubicon on EWS4800 — Tanaka Akira <akr@...17n.org> 2002/09/21

In article <200209211628.g8LGSxp04786@sharui.nakada.kanuma.tochigi.jp>,

[#18342] Re: rubicon on EWS4800 — nobu.nakada@... 2002/09/21

なかだです。

[#18343] Re: rubicon on EWS4800 — Tanaka Akira <akr@...17n.org> 2002/09/21

In article <200209211739.g8LHdKp05495@sharui.nakada.kanuma.tochigi.jp>,

[#18345] Re: rubicon on EWS4800 — nobu.nakada@... 2002/09/22

なかだです。

[#18349] Re: rubicon on EWS4800 — Tanaka Akira <akr@...17n.org> 2002/09/22

In article <200209220415.g8M4Fkp24392@sharui.nakada.kanuma.tochigi.jp>,

[#18374] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — WATANABE Hirofumi <eban@...>

わたなべです。

20 messages 2002/09/25
[#18376] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — matz@... (Yukihiro Matsumoto) 2002/09/25

まつもと ゆきひろです

[#18377] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — nobu.nakada@... 2002/09/25

なかだです。

[#18378] Re: [ruby-cvs] ruby/ext/tcltklib: * eval.c (ruby_run): should set toplevel visibility again here. — WATANABE Hirofumi <eban@...> 2002/09/25

わたなべです。

[ruby-dev:18184] Re: autoload patch for ruby-1.7

From: "Yoshinori K. Okuji" <okuji@...>
Date: 2002-09-05 06:11:53 UTC
List: ruby-dev #18184
At Thu, 5 Sep 2002 12:28:30 +0900,
nobu.nakada@nifty.ne.jp wrote:
> load中のファイルからautoloadされる定数を未定義とみなすようにし
> てみました。結局ev_const_defined()での対応も必要になったり、関
> 数の構成を変えたりしたので、ちょっと大きいですがパッチを作り直
> しました。

ありがとうございます。非常に良好な動作で、make testはパッチを当てる前
より若干速いほどです。

ただ、わざとおかしいスクリプトを与えるとSegmentation faultが起きました。

$ cp /dev/null foo.rb
$ ruby -e 'autoload :FOO, "foo"; autoload :BAR, "foo"; p FOO'
-e:1: [BUG] Segmentation fault
ruby 1.7.3 (2002-09-05) [i686-linux]
Abort

autoload_deleteがst_deleteの返り値を見てなくて、st_deleteが失敗した場
合にNULLを返してしまうのが原因だったので、それを直したパッチを添付しま
す。

> [ruby-dev:18139]の
> > それなり速くて素直なのは、逆方向のハッシュテーブルを別に持ち、あるファ
> > イルからautoloadされるべき定数のリストを簡単に見られるようにしておく方
> > 法です。
> とどっちがいいか…。

中田さんの方法は非常に実装がシンプルなので、このままで良いのではないか
という気がします。

おくじ

Index: class.c
===================================================================
RCS file: /src/ruby/class.c,v
retrieving revision 1.45
diff -u -r1.45 class.c
--- class.c	2002/09/04 06:37:35	1.45
+++ class.c	2002/09/05 06:11:20
@@ -189,9 +189,6 @@
     ID id;
 
     id = rb_intern(name);
-    if (rb_autoload_defined(id)) {
-	rb_autoload_load(id);
-    }
     if (rb_const_defined(rb_cObject, id)) {
 	klass = rb_const_get(rb_cObject, id);
 	if (TYPE(klass) != T_CLASS) {
@@ -278,9 +275,6 @@
     ID id;
 
     id = rb_intern(name);
-    if (rb_autoload_defined(id)) {
-	rb_autoload_load(id);
-    }
     if (rb_const_defined(rb_cObject, id)) {
 	module = rb_const_get(rb_cObject, id);
 	if (TYPE(module) == T_MODULE)
Index: eval.c
===================================================================
RCS file: /src/ruby/eval.c,v
retrieving revision 1.324
diff -u -r1.324 eval.c
--- eval.c	2002/09/05 04:15:50	1.324
+++ eval.c	2002/09/05 06:11:21
@@ -1534,12 +1534,16 @@
     VALUE self;
 {
     NODE *cbase = cref;
+    VALUE result;
 
     while (cbase && cbase->nd_next) {
 	struct RClass *klass = RCLASS(cbase->nd_clss);
 
 	if (NIL_P(klass)) return rb_const_defined(CLASS_OF(self), id);
-	if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, 0)) {
+	if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, &result)) {
+	    if (result == Qundef && NIL_P(rb_autoload_p((VALUE)klass, id))) {
+		return Qfalse;
+	    }
 	    return Qtrue;
 	}
 	cbase = cbase->nd_next;
@@ -1560,7 +1564,11 @@
 	VALUE klass = cbase->nd_clss;
 
 	if (NIL_P(klass)) return rb_const_get(CLASS_OF(self), id);
-	if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &result)) {
+	while (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &result)) {
+	    if (result == Qundef) {
+		rb_autoload_load(klass, id);
+		continue;
+	    }
 	    return result;
 	}
 	cbase = cbase->nd_next;
@@ -3299,9 +3307,7 @@
 		super = 0;
 	    }
 
-	    if ((ruby_class == rb_cObject) && rb_autoload_defined(node->nd_cname)) {
-		rb_autoload_load(node->nd_cname);
-	    }
+	    klass = 0;
 	    if (rb_const_defined_at(ruby_class, node->nd_cname)) {
 		klass = rb_const_get(ruby_class, node->nd_cname);
 		if (TYPE(klass) != T_CLASS) {
@@ -3341,10 +3347,8 @@
 
 	    if (NIL_P(ruby_class)) {
 		rb_raise(rb_eTypeError, "no outer class/module");
-	    }
-	    if ((ruby_class == rb_cObject) && rb_autoload_defined(node->nd_cname)) {
-		rb_autoload_load(node->nd_cname);
 	    }
+	    module = 0;
 	    if (rb_const_defined_at(ruby_class, node->nd_cname)) {
 		module = rb_const_get(ruby_class, node->nd_cname);
 		if (TYPE(module) != T_MODULE) {
@@ -6161,8 +6165,44 @@
 
     rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
 }
+
+static VALUE
+rb_mod_autoload(mod, sym, file)
+    VALUE mod;
+    VALUE sym;
+    VALUE file;
+{
+    ID id = rb_to_id(sym);
+
+    Check_SafeStr(file);
+    rb_autoload(mod, id, RSTRING(file)->ptr);
+    return Qnil;
+}
+
+static VALUE
+rb_mod_autoload_p(mod, sym)
+    VALUE mod, sym;
+{
+    return rb_autoload_p(mod, rb_to_id(sym));
+}
+
+static VALUE
+rb_f_autoload(obj, sym, file)
+    VALUE obj;
+    VALUE sym;
+    VALUE file;
+{
+    return rb_mod_autoload(ruby_class, sym, file);
+}
 
-VALUE rb_f_autoload();
+static VALUE
+rb_f_autoload_p(obj, sym)
+    VALUE obj;
+    VALUE sym;
+{
+    /* use ruby_class as same as rb_f_autoload. */
+    return rb_mod_autoload_p(ruby_class, sym);
+}
 
 void
 Init_load()
@@ -6177,7 +6217,10 @@
 
     rb_define_global_function("load", rb_f_load, -1);
     rb_define_global_function("require", rb_f_require, 1);
+    rb_define_method(rb_cModule, "autoload",  rb_mod_autoload,   2);
+    rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
     rb_define_global_function("autoload", rb_f_autoload, 2);
+    rb_define_global_function("autoload?", rb_f_autoload_p, 1);
     rb_global_variable(&ruby_wrapper);
 
     ruby_dln_librefs = rb_ary_new();
Index: intern.h
===================================================================
RCS file: /src/ruby/intern.h,v
retrieving revision 1.95
diff -u -r1.95 intern.h
--- intern.h	2002/09/03 10:00:45	1.95
+++ intern.h	2002/09/05 06:11:21
@@ -399,8 +399,9 @@
 void rb_set_class_path _((VALUE, VALUE, const char*));
 VALUE rb_path2class _((const char*));
 void rb_name_class _((VALUE, ID));
-void rb_autoload _((const char*, const char*));
-VALUE rb_f_autoload _((VALUE, VALUE, VALUE));
+void rb_autoload _((VALUE, ID, const char*));
+void rb_autoload_load _((VALUE, ID));
+VALUE rb_autoload_p _((VALUE, ID));
 void rb_gc_mark_global_tbl _((void));
 VALUE rb_f_trace_var _((int, VALUE*));
 VALUE rb_f_untrace_var _((int, VALUE*));
@@ -424,14 +425,12 @@
 VALUE rb_mod_constants _((VALUE));
 VALUE rb_mod_remove_const _((VALUE, VALUE));
 int rb_const_defined_at _((VALUE, ID));
-int rb_autoload_defined _((ID));
 int rb_const_defined _((VALUE, ID));
 VALUE rb_const_get _((VALUE, ID));
 VALUE rb_const_get_at _((VALUE, ID));
 void rb_const_set _((VALUE, ID, VALUE));
 void rb_const_assign _((VALUE, ID, VALUE));
 VALUE rb_mod_constants _((VALUE));
-void rb_autoload_load _((ID));
 VALUE rb_cvar_defined _((VALUE, ID));
 void rb_cvar_set _((VALUE, ID, VALUE, int));
 VALUE rb_cvar_get _((VALUE, ID));
Index: variable.c
===================================================================
RCS file: /src/ruby/variable.c,v
retrieving revision 1.68
diff -u -r1.68 variable.c
--- variable.c	2002/09/03 05:20:07	1.68
+++ variable.c	2002/09/05 06:11:21
@@ -20,12 +20,14 @@
 
 static st_table *rb_global_tbl;
 st_table *rb_class_tbl;
+static ID autoload;
 
 void
 Init_var_tables()
 {
     rb_global_tbl = st_init_numtable();
     rb_class_tbl = st_init_numtable();
+    autoload = rb_intern("__autoload__");
 }
 
 struct fc_result {
@@ -253,39 +255,6 @@
     rb_iv_set(klass, "__classid__", ID2SYM(id));
 }
 
-static st_table *autoload_tbl = 0;
-
-static void
-rb_autoload_id(id, filename)
-    ID id;
-    const char *filename;
-{
-    rb_secure(4);
-    if (!rb_is_const_id(id)) {
-	rb_name_error(id, "autoload must be constant name");
-    }
-
-    if (!autoload_tbl) {
-	autoload_tbl = st_init_numtable();
-    }
-    st_insert(autoload_tbl, id, strdup(filename));
-}
-
-void
-rb_autoload(klass, filename)
-    const char *klass, *filename;
-{
-    rb_autoload_id(rb_intern(klass), filename);
-}
-
-VALUE
-rb_f_autoload(obj, klass, file)
-    VALUE obj, klass, file;
-{
-    rb_autoload_id(rb_to_id(klass), StringValuePtr(file));
-    return Qnil;
-}
-
 char *
 rb_class2name(klass)
     VALUE klass;
@@ -1078,6 +1047,140 @@
     return Qnil;		/* not reached */
 }
 
+NORETURN(static void uninitialized_constant _((VALUE, ID)));
+static void
+uninitialized_constant(klass, id)
+    VALUE klass;
+    ID id;
+{
+    if (klass && klass != rb_cObject)
+	rb_name_error(id, "uninitialized constant %s::%s",
+		      RSTRING(rb_class_path(klass))->ptr,
+		      rb_id2name(id));
+    else {
+	rb_name_error(id, "uninitialized constant %s",rb_id2name(id));
+    }
+}
+
+void
+rb_autoload(mod, id, file)
+    VALUE mod;
+    ID id;
+    const char *file;
+{
+    VALUE av;
+    struct st_table *tbl;
+
+    if (!rb_is_const_id(id)) {
+	rb_raise(rb_eNameError, "autoload must be constant name",
+		 rb_id2name(id));
+    }
+    if (!file || !*file) {
+	rb_raise(rb_eArgError, "empty file name");
+    }
+
+    if ((tbl = RCLASS(mod)->iv_tbl) && st_lookup(tbl, id, &av) && av != Qundef)
+	return;
+
+    rb_const_set(mod, id, Qundef);
+    tbl = RCLASS(mod)->iv_tbl;
+    if (st_lookup(tbl, autoload, &av)) {
+	tbl = (struct st_table*)DATA_PTR(av);
+    }
+    else {
+	av = Data_Wrap_Struct(rb_cData, rb_mark_tbl, st_free_table, 0);
+	st_add_direct(tbl, autoload, av);
+	DATA_PTR(av) = tbl = st_init_numtable();
+    }
+    st_insert(tbl, id, rb_str_new2(file));
+}
+
+static VALUE
+autoload_delete(mod, id)
+    VALUE mod;
+    ID id;
+{
+    VALUE val, file = Qnil;
+
+    if (st_lookup(RCLASS(mod)->iv_tbl, autoload, &val)) {
+	struct st_table *tbl = DATA_PTR(val);
+
+	if (!st_delete(tbl, &id, &file)) return Qnil;
+	
+	if (!tbl->num_entries) {
+	    DATA_PTR(val) = 0;
+	    st_free_table(tbl);
+	    id = autoload;
+	    if (st_delete(RCLASS(mod)->iv_tbl, &id, &val)) {
+		rb_gc_force_recycle(val);
+	    }
+	}
+    }
+
+    return file;
+}
+
+void
+rb_autoload_load(klass, id)
+    VALUE klass;
+    ID id;
+{
+    VALUE file, value;
+
+    file = autoload_delete(klass, id);
+    if (NIL_P(file)) {
+	uninitialized_constant(klass, id);
+    }
+    if (rb_provided(RSTRING(file)->ptr)) {
+	uninitialized_constant(klass, id);
+    }
+    FL_UNSET(file, FL_TAINT);
+    rb_f_require(Qnil, file);
+}
+
+static VALUE
+autoload_file(mod, id)
+    VALUE mod;
+    ID id;
+{
+    VALUE val, file;
+    struct st_table *tbl;
+
+    if (!st_lookup(RCLASS(mod)->iv_tbl, autoload, &val) ||
+	!(tbl = DATA_PTR(val)) || !st_lookup(tbl, id, &file)) {
+	return Qnil;
+    }
+    if (!rb_provided(RSTRING(file)->ptr)) {
+	return file;
+    }
+
+    /* already loaded but not defined */
+    st_delete(tbl, &id, 0);
+    if (!tbl->num_entries) {
+	DATA_PTR(val) = 0;
+	st_free_table(tbl);
+	id = autoload;
+	if (st_delete(RCLASS(mod)->iv_tbl, &id, &val)) {
+	    rb_gc_force_recycle(val);
+	}
+    }
+    return Qnil;
+}
+
+VALUE
+rb_autoload_p(mod, id)
+    VALUE mod;
+    ID id;
+{
+    struct st_table *tbl = RCLASS(mod)->iv_tbl;
+    VALUE val;
+
+    if (!tbl || !st_lookup(tbl, id, &val) || val != Qundef) {
+	return Qnil;
+    }
+    return autoload_file(mod, id);
+}
+
 static int
 top_const_get(id, klassp)
     ID id;
@@ -1085,13 +1188,6 @@
 {
     /* pre-defined class */
     if (st_lookup(rb_class_tbl, id, klassp)) return Qtrue;
-
-    /* autoload */
-    if (autoload_tbl && st_lookup(autoload_tbl, id, 0)) {
-	rb_autoload_load(id);
-	*klassp = rb_const_get(rb_cObject, id);
-	return Qtrue;
-    }
     return Qfalse;
 }
 
@@ -1102,36 +1198,20 @@
 {
     VALUE value;
 
-    if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &value)) {
+    while (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &value)) {
+	if (value == Qundef) {
+	    rb_autoload_load(klass, id);
+	    continue;
+	}
 	return value;
     }
     if (klass == rb_cObject && top_const_get(id, &value)) {
 	return value;
     }
-    rb_name_error(id, "uninitialized constant %s::%s",
-		  RSTRING(rb_class_path(klass))->ptr,
-		  rb_id2name(id));
+    uninitialized_constant(klass, id);
     return Qnil;		/* not reached */
 }
 
-void
-rb_autoload_load(id)
-    ID id;
-{
-    char *modname;
-    VALUE module;
-
-    st_delete(autoload_tbl, &id, &modname);
-    if (rb_provided(modname)) {
-	free(modname);
-	return;
-    }
-    module = rb_str_new2(modname);
-    free(modname);
-    FL_UNSET(module, FL_TAINT);
-    rb_f_require(Qnil, module);
-}
-
 VALUE
 rb_const_get(klass, id)
     VALUE klass;
@@ -1143,7 +1223,11 @@
     tmp = klass;
   retry:
     while (tmp) {
-	if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
+	while (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
+	    if (value == Qundef) {
+		rb_autoload_load(tmp, id);
+		continue;
+	    }
 	    return value;
 	}
 	if (tmp == rb_cObject && top_const_get(id, &value)) return value;
@@ -1155,15 +1239,7 @@
 	goto retry;
     }
 
-    /* Uninitialized constant */
-    if (klass && klass != rb_cObject) {
-	rb_name_error(id, "uninitialized constant %s at %s",
-		      rb_id2name(id),
-		      RSTRING(rb_class_path(klass))->ptr);
-    }
-    else { /* global_uninitialized */
-	rb_name_error(id, "uninitialized constant %s",rb_id2name(id));
-    }
+    uninitialized_constant(klass, id);
     return Qnil;		/* not reached */
 }
 
@@ -1182,6 +1258,7 @@
     if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
 
     if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, &id, &val)) {
+	if (val == Qundef) autoload_delete(mod, id);
 	return val;
     }
     if (rb_const_defined_at(mod, id)) {
@@ -1207,18 +1284,6 @@
     return ST_CONTINUE;
 }
 
-static int
-autoload_i(key, name, tbl)
-    ID key;
-    const char *name;
-    st_table *tbl;
-{
-    if (!st_lookup(tbl, key, 0)) {
-	st_insert(tbl, key, key);
-    }
-    return ST_CONTINUE;
-}
-
 void*
 rb_mod_const_at(mod, data)
     VALUE mod;
@@ -1233,9 +1298,6 @@
     }
     if ((VALUE)mod == rb_cObject) {
 	st_foreach(rb_class_tbl, sv_i, tbl);
-	if (autoload_tbl) {
-	    st_foreach(autoload_tbl, autoload_i, tbl);
-	}
     }
     return tbl;
 }
@@ -1289,7 +1351,11 @@
     VALUE klass;
     ID id;
 {
-    if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, 0)) {
+    VALUE value;
+
+    if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &value)) {
+	if (value == Qundef && NIL_P(autoload_file(klass, id)))
+	    return Qfalse;
 	return Qtrue;
     }
     if (klass == rb_cObject) {
@@ -1299,23 +1365,16 @@
 }
 
 int
-rb_autoload_defined(id)
-    ID id;
-{
-    if (autoload_tbl && st_lookup(autoload_tbl, id, 0))
-	return Qtrue;
-    return Qfalse;
-}
-
-int
 rb_const_defined(klass, id)
     VALUE klass;
     ID id;
 {
-    VALUE tmp = klass;
+    VALUE tmp = klass, value;
 
     while (tmp) {
-	if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) {
+	if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl, id, &value)) {
+	    if (value == Qundef && NIL_P(autoload_file(klass, id)))
+		return Qfalse;
 	    return Qtrue;
 	}
 	tmp = RCLASS(tmp)->super;
@@ -1325,7 +1384,7 @@
     }
     if (st_lookup(rb_class_tbl, id, 0))
 	return Qtrue;
-    return rb_autoload_defined(id);
+    return Qfalse;
 }
 
 static void
@@ -1344,8 +1403,13 @@
 	RCLASS(klass)->iv_tbl = st_init_numtable();
     }
     else if (isconst) {
-	if (st_lookup(RCLASS(klass)->iv_tbl, id, 0) ||
+	VALUE value = Qfalse;
+
+	if (st_lookup(RCLASS(klass)->iv_tbl, id, &value) ||
 	    (klass == rb_cObject && st_lookup(rb_class_tbl, id, 0))) {
+	    if (value == Qundef)
+		autoload_delete(klass, id);
+	    else
 	    rb_warn("already initialized %s %s", dest, rb_id2name(id));
 	}
     }
@@ -1383,25 +1447,8 @@
 	st_insert(RCLASS(rb_cObject)->iv_tbl, id, val);
 	return;
     }
-
-    /* autoload */
-    if (autoload_tbl && st_lookup(autoload_tbl, id, 0)) {
-	char *modname;
-
-	st_delete(autoload_tbl, &id, &modname);
-	free(modname);
-	st_insert(RCLASS(rb_cObject)->iv_tbl, id, val);
-	return;
-    }
 
-    /* Uninitialized constant */
-    if (klass && klass != rb_cObject)
-	rb_name_error(id, "uninitialized constant %s::%s",
-		      RSTRING(rb_class_path(klass))->ptr,
-		      rb_id2name(id));
-    else {
-	rb_name_error(id, "uninitialized constant %s",rb_id2name(id));
-    }
+    uninitialized_constant(klass, id);
 }
 
 void

In This Thread