[#16211] pstore.rb and sync.rb — Kazuhiro NISHIYAMA <zn@...>

西山和広です。

19 messages 2002/03/04
[#16245] Re: pstore.rb and sync.rb — keiju@... (石塚圭樹) 2002/03/07

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

[#16240] [Oni Guruma] look behind — nobu.nakada@...

なかだです。

14 messages 2002/03/07

[#16283] ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

124 messages 2002/03/08
[#16307] Re: ライブラリ拡大計画 — TAKAHASHI Masayoshi <maki@...> 2002/03/10

高橋征義です。

[#16317] Re: ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto) 2002/03/11

まつもと ゆきひろです

[#16318] Re: ライブラリ拡大計画 — Tanaka Akira <akr@...17n.org> 2002/03/11

In article <1015827556.101112.6552.nullmailer@ev.netlab.jp>,

[#16320] Re: ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto) 2002/03/11

まつもと ゆきひろです

[#16347] Re: ライブラリ拡大計画 — Minero Aoki <aamine@...> 2002/03/12

あおきです。

[#16308] Re: ライブラリ拡大計画 — WATANABE Hirofumi <eban@...> 2002/03/11

わたなべです。

[#16626] Re: ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto) 2002/03/27

まつもと ゆきひろです

[#16628] Re: ライブラリ拡大計画 — Takaaki Tateishi <ttate@...> 2002/03/27

At Wed, 27 Mar 2002 18:56:03 +0900,

[#16629] Re: ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto) 2002/03/27

まつもと ゆきひろです

[#16647] Re: ライブラリ拡大計画 — Takaaki Tateishi <ttate@...> 2002/03/28

At Thu, 28 Mar 2002 00:12:49 +0900,

[#16674] Re: ライブラリ拡大計画 — Takaaki Tateishi <ttate@...> 2002/03/29

At Thu, 28 Mar 2002 23:45:49 +0900,

[#16675] Re: ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto) 2002/03/29

まつもと ゆきひろです

[#16680] Re: ライブラリ拡大計画 — nobu.nakada@... 2002/03/29

なかだです。

[#16681] Re: ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto) 2002/03/29

まつもと ゆきひろです

[#16683] Re: ライブラリ拡大計画 — nobu.nakada@... 2002/03/29

なかだです。

[#16687] Re: ライブラリ拡大計画 — Takaaki Tateishi <ttate@...> 2002/03/30

At Fri, 29 Mar 2002 20:32:17 +0900,

[#16718] Re: ライブラリ拡大計画 — Takaaki Tateishi <ttate@...> 2002/04/02

At Sun, 31 Mar 2002 02:20:04 +0900,

[#16371] Re: ライブラリ拡大計画 — Takaaki Tateishi <ttate@...> 2002/03/13

At Fri, 8 Mar 2002 18:05:01 +0900,

[#16373] Re: ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto) 2002/03/14

まつもと ゆきひろです

[#16397] Re: ライブラリ拡大計画 — nobu.nakada@... 2002/03/14

なかだです。

[#16404] Re: ライブラリ拡大計画 — Tanaka Akira <akr@...17n.org> 2002/03/14

In article <20020314133401.3918E10F3@sharui.nakada.kanuma.tochigi.jp>,

[#16406] Re: ライブラリ拡大計画 — nobu.nakada@... 2002/03/15

なかだです。

[#16290] IO#gets improvement — nobu.nakada@...

なかだです。

27 messages 2002/03/08
[#16291] Re: IO#gets improvement — Tanaka Akira <akr@...17n.org> 2002/03/08

In article <20020308131426.8C36123B9@sharui.nakada.kanuma.tochigi.jp>,

[#16294] Re: IO#gets improvement — nobu.nakada@... 2002/03/09

なかだです。

[#16549] Re: IO#gets improvement — nobu.nakada@... 2002/03/23

なかだです。

[#16486] mswin32 configuration — nobu.nakada@...

なかだです。

20 messages 2002/03/19
[#16488] Re: mswin32 configuration — "U.Nakamura" <usa@...> 2002/03/19

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

[#16489] Re: mswin32 configuration — nobu.nakada@... 2002/03/19

なかだです。

[#16490] Re: mswin32 configuration — "U.Nakamura" <usa@...> 2002/03/19

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

[#16545] BigFloat — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

51 messages 2002/03/23
[#16547] Re: BigFloat — "Akinori MUSHA" <knu@...> 2002/03/23

At Sat, 23 Mar 2002 22:55:45 +0900,

[#16548] Re: BigFloat — "Akinori MUSHA" <knu@...> 2002/03/23

At Sun, 24 Mar 2002 02:20:26 +0900,

[#16550] Re: BigFloat — Tanaka Akira <akr@...17n.org> 2002/03/23

In article <867ko3yyik.wl@archon.local.idaemons.org>,

[#16551] Re: BigFloat — "Akinori MUSHA" <knu@...> 2002/03/23

At Sun, 24 Mar 2002 04:21:59 +0900,

[#16552] Re: BigFloat — Tanaka Akira <akr@...17n.org> 2002/03/23

In article <864rj7yljs.wl@archon.local.idaemons.org>,

[#16553] Re: BigFloat — "Akinori MUSHA" <knu@...> 2002/03/23

At Sun, 24 Mar 2002 07:44:15 +0900,

[#16560] Re: BigFloat — Tanaka Akira <akr@...17n.org> 2002/03/24

In article <861yeazvtg.wl@archon.local.idaemons.org>,

[#16565] Re: BigFloat — "Akinori MUSHA" <knu@...> 2002/03/24

At Sun, 24 Mar 2002 15:41:18 +0900,

[#16575] Re: if Re: BigFloat — keiju@... (石塚圭樹) 2002/03/24

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

[#16715] Re: if Re: BigFloat — keiju@... (石塚圭樹) 2002/04/02

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

[#16725] Re: if Re: BigFloat — "Akinori MUSHA" <knu@...> 2002/04/02

At Tue, 2 Apr 2002 16:16:04 +0900,

[#16789] Re: if Re: BigFloat — "Shigeo Kobayashi" <shigeo@...> 2002/04/08

[#16805] Re: if Re: BigFloat — Shin-ichiro HARA <sinara@...> 2002/04/09

原です。

[#16811] Re: if Re: BigFloat — "Shigeo Kobayashi" <shigeo@...> 2002/04/09

[#16555] File.fnmatch (Re: [rubyist:1286] Re: ARGV の機能) — Koji Arai <JCA02266@...>

新井です。

11 messages 2002/03/24

[#16593] Oniguruma and multibyte character literal — TAKAHASHI Masayoshi <maki@...>

高橋征義です。

15 messages 2002/03/25
[#16594] Re: Oniguruma and multibyte character literal — matz@... (Yukihiro Matsumoto) 2002/03/25

まつもと ゆきひろです

[#16652] [OniGuruma] nested repeat operator — "K.Kosako" <kosako@...>

[ruby-talk:36959]で指摘された

31 messages 2002/03/29
[#16669] Re: [OniGuruma] nested repeat operator — Tanaka Akira <akr@...17n.org> 2002/03/29

In article <20020329022810.68F9E17@helium.ruby-lang.org>,

[#16676] Re: [OniGuruma] nested repeat operator — "K.Kosako" <kosako@...> 2002/03/29

Tanaka Akiraさんの<hvohemzoku6.fsf@coulee.a02.aist.go.jp>から

[ruby-dev:16180] Re: autoload (Re: Re: : and ::)

From: MOROHOSHI Akihiko <moro@...>
Date: 2002-03-03 11:51:43 UTC
List: ruby-dev #16180
なかださん wrote:
> > +static VALUE autoload_tbl = 0;
> > +static VALUE autoload_target = 0;
> > +#define AUTOLOAD_TARGET		autoload_target
> > +#define IS_AUTOLOAD_TARGET(obj)	((obj)==autoload_target)
> 
> Qundefでもいいかも。

なるほど、それを使うのが良さそうですね。

というわけで、変更してみました。
先の差分からの変更点は、他に以下の点です。
 - 1.6.7を元にした
 - 定数書き換え時のautoload情報削除し忘れを修正
 - rb_hash_delete()を直接使うようにした
 - autoload?(mod,sym) を mod.autoload?(sym) に変更

--
MOROHOSHI Akihiko

Attachments (1)

ruby-1.6.7-autoload.patch (12 KB, text/x-diff)
diff -ruN --exclude config* --exclude *~ --exclude Makefile --exclude ext --exclude *.rb ruby-1.6.7.orig/eval.c ruby-1.6.7/eval.c
--- ruby-1.6.7.orig/eval.c	Wed Feb 27 13:50:29 2002
+++ ruby-1.6.7/eval.c	Sun Mar  3 19:15:23 2002
@@ -3079,9 +3079,6 @@
 	    }
 
 	    klass = 0;
-	    if ((ruby_class == rb_cObject) && rb_autoload_defined(node->nd_cname)) {
-		rb_autoload_load(node->nd_cname);
-	    }
 	    if (rb_const_defined_at(ruby_class, node->nd_cname)) {
 		klass = rb_const_get(ruby_class, node->nd_cname);
 	    }
@@ -3126,9 +3123,6 @@
 		rb_raise(rb_eTypeError, "no outer class/module");
 	    }
 	    module = 0;
-	    if ((ruby_class == rb_cObject) && rb_autoload_defined(node->nd_cname)) {
-		rb_autoload_load(node->nd_cname);
-	    }
 	    if (rb_const_defined_at(ruby_class, node->nd_cname)) {
 		module = rb_const_get(ruby_class, node->nd_cname);
 	    }
@@ -6057,8 +6051,6 @@
 #endif
 }
 
-VALUE rb_f_autoload();
-
 void
 Init_load()
 {
@@ -6072,7 +6064,6 @@
 
     rb_define_global_function("load", rb_f_load, -1);
     rb_define_global_function("require", rb_f_require, 1);
-    rb_define_global_function("autoload", rb_f_autoload, 2);
     rb_global_variable(&ruby_wrapper);
 
     ruby_dln_librefs = rb_ary_new();
diff -ruN --exclude config* --exclude *~ --exclude Makefile --exclude ext --exclude *.rb ruby-1.6.7.orig/hash.c ruby-1.6.7/hash.c
--- ruby-1.6.7.orig/hash.c	Mon Feb 25 18:16:41 2002
+++ ruby-1.6.7/hash.c	Sun Mar  3 19:34:02 2002
@@ -386,7 +386,7 @@
     return indexes;
 }
 
-static VALUE
+VALUE
 rb_hash_delete(hash, key)
     VALUE hash, key;
 {
diff -ruN --exclude config* --exclude *~ --exclude Makefile --exclude ext --exclude *.rb ruby-1.6.7.orig/inits.c ruby-1.6.7/inits.c
--- ruby-1.6.7.orig/inits.c	Wed Mar 21 17:04:11 2001
+++ ruby-1.6.7/inits.c	Sun Mar  3 20:01:02 2002
@@ -13,6 +13,7 @@
 #include "ruby.h"
 
 void Init_Array _((void));
+void Init_autoload _((void));
 void Init_Bignum _((void));
 void Init_Comparable _((void));
 void Init_Dir _((void));
@@ -72,6 +73,7 @@
     Init_signal();
     Init_process();
     Init_load();
+    Init_autoload();
     Init_Proc();
     Init_Math();
     Init_GC();
diff -ruN --exclude config* --exclude *~ --exclude Makefile --exclude ext --exclude *.rb ruby-1.6.7.orig/intern.h ruby-1.6.7/intern.h
--- ruby-1.6.7.orig/intern.h	Wed Feb 27 13:50:30 2002
+++ ruby-1.6.7/intern.h	Sun Mar  3 19:34:40 2002
@@ -200,6 +200,7 @@
 VALUE rb_hash_freeze _((VALUE));
 VALUE rb_hash_aref _((VALUE, VALUE));
 VALUE rb_hash_aset _((VALUE, VALUE, VALUE));
+VALUE rb_hash_delete _((VALUE, VALUE));
 VALUE rb_hash_delete_if _((VALUE));
 int rb_path_check _((char *));
 int rb_env_path_tainted _((void));
@@ -358,8 +359,6 @@
 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_gc_mark_global_tbl _((void));
 VALUE rb_f_trace_var _((int, VALUE*));
 VALUE rb_f_untrace_var _((int, VALUE*));
@@ -380,14 +379,12 @@
 VALUE rb_mod_const_of _((VALUE, 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));
 void rb_cvar_declare _((VALUE, ID, VALUE));
 VALUE rb_cvar_defined _((VALUE, ID));
 void rb_cvar_set _((VALUE, ID, VALUE));
diff -ruN --exclude config* --exclude *~ --exclude Makefile --exclude ext --exclude *.rb ruby-1.6.7.orig/variable.c ruby-1.6.7/variable.c
--- ruby-1.6.7.orig/variable.c	Tue Feb 19 13:48:04 2002
+++ ruby-1.6.7/variable.c	Sun Mar  3 20:18:26 2002
@@ -245,40 +245,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_raise(rb_eNameError, "autoload must be constant name",
-		 rb_id2name(id));
-    }
-
-    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), STR2CSTR(file));
-    return Qnil;
-}
-
 char *
 rb_class2name(klass)
     VALUE klass;
@@ -1032,22 +998,115 @@
     return val;
 }
 
+static VALUE autoload_tbl = Qnil;
+#define AUTOLOAD_TARGET			Qundef
+#define IS_AUTOLOAD_TARGET(obj)		((obj)==Qundef)
+#define AUTOLOAD_KEY_NEW(klass,id)	rb_ary_new3(2,klass,ID2SYM(id))
+
+static void
+autoload_add(VALUE klass, ID id, VALUE file) {
+    VALUE key;
+    
+    rb_secure(4);
+    Check_SafeStr(file);
+    if (!rb_is_const_id(id)) {
+	rb_raise(rb_eNameError, "autoload must be constant name",
+		 rb_id2name(id));
+    }
+
+    key = AUTOLOAD_KEY_NEW(klass, id);
+    rb_hash_aset(autoload_tbl, key, file);
+}
+
+static VALUE
+rb_mod_autoload(VALUE mod, VALUE sym, VALUE file) {
+    ID id = rb_to_id(sym);
+
+    if (rb_const_defined_at(mod,id))
+	return Qnil;
+
+    rb_const_set(mod, id, AUTOLOAD_TARGET);
+    autoload_add(mod, id, file);
+
+    return Qnil;
+}
+
+static VALUE
+rb_f_autoload(VALUE obj, VALUE sym, VALUE file) {
+    /* I use ruby_class instead of obj, as same as NODE_CDECL,
+     * assuming autoload is another way of const_set.
+     */
+    return rb_mod_autoload(ruby_class, sym, file);
+}
+
+static void
+autoload_delete(VALUE klass, VALUE id) {
+    VALUE key = AUTOLOAD_KEY_NEW(klass, id);
+    rb_hash_delete(autoload_tbl, key);
+}
+
+static void
+autoload_load(VALUE klass, ID id) {
+    VALUE key, file;
+
+    if (RCLASS(klass)->iv_tbl) {
+	VALUE value;
+	st_delete(ROBJECT(klass)->iv_tbl, &id, &value);
+	if (! IS_AUTOLOAD_TARGET(value))
+	    rb_bug("autoload_laod: removed normal constant: %s::%s",
+		   rb_class2name(klass), rb_id2name(id));
+    } else {
+	rb_bug("autoload_load: constant not found: %s::%s",
+	       rb_class2name(klass), rb_id2name(id));
+    }
+
+    key = AUTOLOAD_KEY_NEW(klass, id);
+    file = rb_hash_delete(autoload_tbl, key);
+
+    if (NIL_P(file)) {
+	rb_bug("autoload file not found for %s::%s",
+	       rb_class2name(klass), rb_id2name(id));
+    }
+
+    if (rb_provided(RSTRING(file)->ptr))
+	return;
+
+    FL_UNSET(file, FL_TAINT);
+    rb_f_require(Qnil, file);
+}
+
+static VALUE
+rb_mod_autoload_p(VALUE mod, VALUE sym) {
+    ID id = rb_to_id(sym);
+    return NIL_P(rb_hash_aref(autoload_tbl, AUTOLOAD_KEY_NEW(mod,id))) ?
+	Qfalse : Qtrue;
+}
+
+static VALUE
+rb_f_autoload_p(VALUE self, VALUE sym) {
+    /* use ruby_class as same as rb_f_autoload. */
+    return rb_mod_autoload_p(ruby_class, sym);
+}
+
+void
+Init_autoload() {
+    autoload_tbl = rb_hash_new();
+    rb_global_variable(&autoload_tbl);
+
+    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);
+}
+
 static int
 top_const_get(id, klassp)
     ID id;
     VALUE *klassp;
 {
-    VALUE value;
-
     /* 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;
 }
 
@@ -1058,7 +1117,12 @@
 {
     VALUE value;
 
+retry:
     if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &value)) {
+	if (IS_AUTOLOAD_TARGET(value)) {
+	    autoload_load(klass, id);
+	    goto retry;
+	}
 	return value;
     }
     if (klass == rb_cObject && top_const_get(id, &value)) {
@@ -1070,24 +1134,6 @@
     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;
@@ -1100,6 +1146,10 @@
   retry:
     while (tmp) {
 	if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
+	    if (IS_AUTOLOAD_TARGET(value)) {
+		autoload_load(tmp,id);
+		goto retry;
+	    }
 	    return value;
 	}
 	if (tmp == rb_cObject && top_const_get(id, &value)) return value;
@@ -1128,6 +1178,7 @@
     VALUE value;
     VALUE ary;
 {
+    /* autoload constants: included. */
     if (rb_is_const_id(key)) {
 	VALUE kval = rb_str_new2(rb_id2name(key));
 	if (!rb_ary_includes(ary, kval)) {
@@ -1152,7 +1203,15 @@
     if (OBJ_FROZEN(mod)) rb_error_frozen("class/module");
 
     if (RCLASS(mod)->iv_tbl && st_delete(ROBJECT(mod)->iv_tbl, &id, &val)) {
-	return val;
+	if (IS_AUTOLOAD_TARGET(val)) {
+	    /* cancel autoload and go through.
+	     *
+	     * XXX - should we do autoload and retry?
+	     */
+	    autoload_delete(mod, id);
+	} else {
+	    return val;
+	}
     }
     if (rb_const_defined_at(mod, id)) {
 	rb_raise(rb_eNameError, "cannot remove %s::%s", 
@@ -1163,19 +1222,6 @@
     return Qnil;		/* not reached */
 }
 
-static int
-autoload_i(key, name, ary)
-    ID key;
-    const char *name;
-    VALUE ary;
-{
-    VALUE kval = rb_str_new2(rb_id2name(key));
-    if (!rb_ary_includes(ary, kval)) {
-	rb_ary_push(ary, kval);
-    }
-    return ST_CONTINUE;
-}
-
 VALUE
 rb_mod_const_at(mod, ary)
     VALUE mod, ary;
@@ -1185,9 +1231,6 @@
     }
     if ((VALUE)mod == rb_cObject) {
 	st_foreach(rb_class_tbl, sv_i, ary);
-	if (autoload_tbl) {
-	    st_foreach(autoload_tbl, autoload_i, ary);
-	}
     }
     return ary;
 }
@@ -1217,6 +1260,7 @@
     VALUE klass;
     ID id;
 {
+    /* autoload constants: included */
     if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, 0)) {
 	return Qtrue;
     }
@@ -1227,21 +1271,13 @@
 }
 
 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;
 
+    /* autoload constants: included */
     while (tmp) {
 	if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) {
 	    return Qtrue;
@@ -1253,7 +1289,7 @@
     }
     if (st_lookup(rb_class_tbl, id, 0))
 	return Qtrue;
-    return rb_autoload_defined(id);
+    return Qfalse;
 }
 
 static void
@@ -1272,8 +1308,12 @@
 	RCLASS(klass)->iv_tbl = st_init_numtable();
     }
     else if (isconst) {
-	if (st_lookup(RCLASS(klass)->iv_tbl, id, 0) ||
-	    (klass == rb_cObject && st_lookup(rb_class_tbl, id, 0))) {
+	VALUE value;
+	if (st_lookup(RCLASS(klass)->iv_tbl, id, &value)) {
+	    if (IS_AUTOLOAD_TARGET(value))
+		autoload_delete(klass, id);
+	    rb_warn("already initialized %s %s", dest, rb_id2name(id));
+	} else if (klass == rb_cObject && st_lookup(rb_class_tbl, id, 0)) {
 	    rb_warn("already initialized %s %s", dest, rb_id2name(id));
 	}
     }
@@ -1297,9 +1337,15 @@
     VALUE val;
 {
     VALUE tmp = klass;
-    
+
+retry:    
     while (tmp) {
-	if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) {
+	VALUE value;
+	if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,&value)) {
+	    if (IS_AUTOLOAD_TARGET(value)) {
+		autoload_load(tmp,id);
+		goto retry;
+	    }
 	    st_insert(RCLASS(tmp)->iv_tbl, id, val);
 	    return;
 	}
@@ -1308,16 +1354,6 @@
     /* pre-defined class */
     if (st_lookup(rb_class_tbl, id, 0)) {
 	st_delete(rb_class_tbl, id, 0);
-	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;
     }

In This Thread