[#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:16165] Re: autoload (Re: Re: : and ::)

From: MOROHOSHI Akihiko <moro@...>
Date: 2002-03-01 21:38:09 UTC
List: ruby-dev #16165
GUI toolkitのような、大きくてかつ一部しか使わないことが多いものを
モジュールにする場合を考えると、なるべくautoloadを残して頂ける方が
よいと思います。

> |>ということで、ほんとはautoloadはなくしたいです。Riteではなく
> |>なるかも。
> |
> |げ、そうなのかあ。しかし、autoload が require したファイルには
> |多分求める定数の定義が書かれているので、その定数に関しては2度
> |と fallback は呼ばれないので、そんなに速度は変わらない気がする
> |んだけど、そうでもないのかな。
> 
> 定数呼び出しのたびに親クラスに聞きに行く前にfallbackの存在を
> チェックしに行かないといけないような気がします。それが馬鹿に
> できないコストのような。

fallbackをチェックしにいく代わりに、
本物のオブジェクトの代わりに autoload することを示すオブジェクトを
代入しておき、const_get でそれが出てきたら autoload するのでは
どうでしょうか。

とっくに考えられていそう、とも思ったのですが、
とりあえず書いてみました。ご笑覧下さい。

autoload :TopMod, "topmod.rb"
や
module TopMod
  autoload :SubMod, "topmod/submod.rb"	# for TopMod::SubMod
end
が出来ます。

以下、
 - サンプルスクリプト
 - 1.6.6からの差分
を添えます。

--
MOROHOSHI Akihiko

Attachments (4)

altest.rb (485 Bytes, text/x-ruby)
ConstA = 1
p ConstA			# => 1

module ModB
end
p ModB				# => ModB

module Foo
    autoload :Bar, "foo_bar.rb"
end

p Foo.const_defined? :Bar	# => true
p Foo::Bar			# ./foo_bar.rb is loaded.
				# => Foo::Bar
p Foo::Bar::A			# => 1

begin
    p Bar::A			# => (NameError)
rescue NameError => e
    puts "Bar::A not found: #{e} (#{e.class})"
    puts "OK, let's continue...."
end

autoload :Bar, "bar.rb"
p Object.const_defined? :Bar	# => true
p Bar::A			# ./bar.rb is loaded.
				# => 2
foo_bar.rb (75 Bytes, text/x-ruby)
module Foo
    class Bar
	A = 1
    end
end

puts "#{__FILE__} is loaded."
bar.rb (55 Bytes, text/x-ruby)
class Bar
    A = 2
end

puts "#{__FILE__} is loaded."
ruby-1.6.6-autoload.patch (12.1 KB, text/x-diff)
diff -ruN --exclude ext --exclude config* --exclude *.rb --exclude Makefile --exclude *~ --exclude variable.c.* ruby-1.6.6.orig/eval.c ruby-1.6.6/eval.c
--- ruby-1.6.6.orig/eval.c	Fri Dec 21 18:19:47 2001
+++ ruby-1.6.6/eval.c	Sat Mar  2 05:18:26 2002
@@ -3072,9 +3072,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);
 	    }
@@ -3118,9 +3115,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);
 	    }
@@ -6025,8 +6019,6 @@
 #endif
 }
 
-VALUE rb_f_autoload();
-
 void
 Init_load()
 {
@@ -6040,7 +6032,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 ext --exclude config* --exclude *.rb --exclude Makefile --exclude *~ --exclude variable.c.* ruby-1.6.6.orig/inits.c ruby-1.6.6/inits.c
--- ruby-1.6.6.orig/inits.c	Wed Mar 21 17:04:11 2001
+++ ruby-1.6.6/inits.c	Sat Mar  2 03:25:36 2002
@@ -13,6 +13,8 @@
 #include "ruby.h"
 
 void Init_Array _((void));
+void Init_autoload_1 _((void));
+void Init_autoload_2 _((void));
 void Init_Bignum _((void));
 void Init_Comparable _((void));
 void Init_Dir _((void));
@@ -50,6 +52,7 @@
     Init_sym();
     Init_var_tables();
     Init_Object();
+    Init_autoload_1();
     Init_Comparable();
     Init_Enumerable();
     Init_Precision();
@@ -72,6 +75,7 @@
     Init_signal();
     Init_process();
     Init_load();
+    Init_autoload_2();
     Init_Proc();
     Init_Math();
     Init_GC();
diff -ruN --exclude ext --exclude config* --exclude *.rb --exclude Makefile --exclude *~ --exclude variable.c.* ruby-1.6.6.orig/intern.h ruby-1.6.6/intern.h
--- ruby-1.6.6.orig/intern.h	Fri Dec 21 18:19:47 2001
+++ ruby-1.6.6/intern.h	Sat Mar  2 05:34:47 2002
@@ -352,8 +352,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*));
@@ -374,14 +372,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 ext --exclude config* --exclude *.rb --exclude Makefile --exclude *~ --exclude variable.c.* ruby-1.6.6.orig/variable.c ruby-1.6.6/variable.c
--- ruby-1.6.6.orig/variable.c	Fri Dec 21 18:20:54 2001
+++ ruby-1.6.6/variable.c	Sat Mar  2 06:10:21 2002
@@ -242,40 +242,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;
@@ -1029,6 +995,117 @@
     return val;
 }
 
+static VALUE autoload_tbl = 0;
+static VALUE autoload_target = 0;
+#define AUTOLOAD_TARGET		autoload_target
+#define IS_AUTOLOAD_TARGET(obj)	((obj)==autoload_target)
+#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) {
+    ID id = rb_to_id(sym);
+
+    /* I use ruby_class as obj as same as NODE_CDECL,
+     * assuming autoload is another representation of rb_const_set.
+     */
+    obj = ruby_class;
+
+    if (rb_const_defined_at(obj, id))
+	return Qnil;
+
+    rb_const_set(obj, id, AUTOLOAD_TARGET);
+    autoload_add(obj, id, file);
+    
+    return Qnil;
+}
+
+static void
+autoload_delete(VALUE klass, VALUE id) {
+    VALUE key;
+    key = AUTOLOAD_KEY_NEW(klass, id);
+    rb_funcall(autoload_tbl, rb_intern("delete"), 1, 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_load: removed normal constant: %s::%s",
+		   rb_class2name(klass), rb_id2name(id));
+    } else {
+	rb_bug("autoload_load: AUTOLOAD_TARGET not found: %s::%s",
+	       rb_class2name(klass), rb_id2name(id));
+    }
+	
+    key = AUTOLOAD_KEY_NEW(klass, id);
+    file = rb_funcall(autoload_tbl, rb_intern("delete"), 1, 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_f_autoload_p(VALUE self, 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;
+}
+
+void
+Init_autoload_1() {
+    autoload_target = rb_obj_alloc(rb_cObject);
+}
+
+void
+Init_autoload_2() {
+    autoload_tbl = rb_hash_new();
+    rb_global_variable(&autoload_tbl);
+
+    rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
+    rb_define_global_function("autoload", rb_f_autoload, 2);
+    rb_define_global_function("autoload?", rb_f_autoload_p, 2);
+}
+
 static int
 top_const_get(id, klassp)
     ID id;
@@ -1039,12 +1116,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;
 }
 
@@ -1055,7 +1126,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)) {
@@ -1067,22 +1143,24 @@
     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);
+/* for debugging purpose. */
+static char buf[1024];
+const char *
+print_class_id(VALUE klass, VALUE id) {
+    const char *ptr = NULL;
+    
+    buf[0] = '\0';
+    if (RTEST(rb_funcall(klass, rb_intern("kind_of?"), 1, rb_cModule))) {
+	strcpy(buf, rb_class2name(klass));
+    } else {
+	strcpy(buf, "??");
+    }
+    ptr = rb_id2name(id);
+    if (ptr)
+	strcat(buf, ptr);
+    else
+	strcat(buf, "(NULL)");
+    return buf;
 }
 
 VALUE
@@ -1097,6 +1175,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;
@@ -1125,6 +1207,7 @@
     VALUE value;
     VALUE ary;
 {
+    /* autoload consideration: include. */
     if (rb_is_const_id(key)) {
 	VALUE kval = rb_str_new2(rb_id2name(key));
 	if (!rb_ary_includes(ary, kval)) {
@@ -1149,7 +1232,14 @@
     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?
+	     */
+	} else {
+	    return val;
+	}
     }
     if (rb_const_defined_at(mod, id)) {
 	rb_raise(rb_eNameError, "cannot remove %s::%s", 
@@ -1160,19 +1250,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;
@@ -1182,9 +1259,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;
 }
@@ -1214,6 +1288,7 @@
     VALUE klass;
     ID id;
 {
+    /* autoload consideration: include. */
     if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, 0)) {
 	return Qtrue;
     }
@@ -1224,21 +1299,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 consideration: include. */
     while (tmp) {
 	if (RCLASS(tmp)->iv_tbl && st_lookup(RCLASS(tmp)->iv_tbl,id,0)) {
 	    return Qtrue;
@@ -1250,7 +1317,7 @@
     }
     if (st_lookup(rb_class_tbl, id, 0))
 	return Qtrue;
-    return rb_autoload_defined(id);
+    return Qfalse;
 }
 
 static void
@@ -1269,8 +1336,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));
 	}
     }
@@ -1295,8 +1366,14 @@
 {
     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;
 	}
@@ -1305,16 +1382,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