[#16154] : and :: — Shin-ichiro HARA <sinara@...>
原です。
まつもと ゆきひろです
原です。
まつもと ゆきひろです
原です。
[#16178] Marshal::dump calls Proc#yield? (1.6.7) — akira yamada / やまだあきら <akira@...>
まつもと ゆきひろです
[#16191] getopts() broken — "Akinori MUSHA" <knu@...>
getopts が最新の 1.6/1.7 で動かなくなっているようなので、
[#16211] pstore.rb and sync.rb — Kazuhiro NISHIYAMA <zn@...>
西山和広です。
けいじゅ@日本ラショナルソフトウェアです.
まつもと ゆきひろです
けいじゅ@日本ラショナルソフトウェアです.
まつもと ゆきひろです
[#16214] net/http.rb version_1_2 not work — Tietew <tietew-ml-ruby-dev@...>
Tietew です。
[#16223] importing racc-runtime — "Akinori MUSHA" <knu@...>
rough にある racc runtime モジュールを眺めていたんですが、
[#16231] LoadLibraryEx vs. LoadLibrary — WATANABE Hirofumi <eban@...>
わたなべです。
[#16240] [Oni Guruma] look behind — nobu.nakada@...
なかだです。
nobu.nakada@nifty.ne.jpさんの
In article <20020307054004.BFADD57D@helium.ruby-lang.org>,
Tanaka Akiraさんの<hvog03clxib.fsf@coulee.a02.aist.go.jp>から
[#16277] Dir::glob(pattern, flags = 0) — "Akinori MUSHA" <knu@...>
しばらく放置していた、
[#16283] ライブラリ拡大計画 — matz@... (Yukihiro Matsumoto)
まつもと ゆきひろです
高橋征義です。
まつもと ゆきひろです
In article <1015827556.101112.6552.nullmailer@ev.netlab.jp>,
まつもと ゆきひろです
なかだです。
あおきです。
まつもと ゆきひろです
In article <hvowuwjbo4j.fsf@coulee.a02.aist.go.jp>,
わたなべです。
At Mon, 11 Mar 2002 12:17:12 +0900,
まつもと ゆきひろです
At Wed, 27 Mar 2002 18:56:03 +0900,
まつもと ゆきひろです
At Thu, 28 Mar 2002 00:12:49 +0900,
At Thu, 28 Mar 2002 23:45:49 +0900,
まつもと ゆきひろです
なかだです。
まつもと ゆきひろです
なかだです。
At Fri, 29 Mar 2002 20:32:17 +0900,
At Sun, 31 Mar 2002 02:20:04 +0900,
At Sun, 31 Mar 2002 02:20:04 +0900,
なかだです。
わたなべです。
At Fri, 8 Mar 2002 18:05:01 +0900,
まつもと ゆきひろです
なかだです。
In article <20020314133401.3918E10F3@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <20020315050614.C975F10F0@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <20020315160435.7A84B114C@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <200204161515.g3GFFjM17207@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <200204170729.g3H7TeM15268@sharui.nakada.kanuma.tochigi.jp>,
[#16290] IO#gets improvement — nobu.nakada@...
なかだです。
In article <20020308131426.8C36123B9@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
In article <20020309025151.5405C24F2@sharui.nakada.kanuma.tochigi.jp>,
なかだです。
なかだです。
わたなべです。
なかだです。
わたなべです。
なかだです。
わたなべです。
なかだです。
わたなべです。
なかだです。
[#16351] map in printf format — nobu.nakada@...
なかだです。
[#16411] block local var — "K.Kosako" <kosako@...>
Version: 1.7 latest
> コンパイル時点で、ブロック変数かどうかの判定が
[#16422] abort with message — nobu.nakada@...
なかだです。
西山和広です。
[#16423] Re: [ruby-list:34301] Re: Enumerable#inject (Re: しぶらぐっ議事録。) — Koji Arai <JCA02266@...>
新井です。
[#16433] class variable & inheritance & singlton method / 1.6.7 — sinara@...
原です。
[#16454] Re: ext/iconv does not work with iconv 2.0 (FreeBSD) (PR#273) — nobu.nakada@...
なかだです。
[#16486] mswin32 configuration — nobu.nakada@...
なかだです。
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
なかだです。
こんにちは、なかむら(う)です。
なかだです。
[#16508] Re: [ruby-cvs] ruby: * mkconfig.rb: don't touch rbconfig.rb if there is a trouble. — "U.Nakamura" <usa@...>
こんにちは、なかむら(う)です。
In article <20020320203914.55E9.USA@osb.att.ne.jp>,
[#16514] MAKEFLAGS for ext — nobu.nakada@...
なかだです。
[#16518] ruby-zlib cvs operation — "Akinori MUSHA" <knu@...>
At Thu, 21 Mar 2002 16:53:03 +0000,
In article <86d6xxerjd.wl@daemon.musha.org>,
新井です。
うえのです。
[#16522] sprintf("%u") — Koji Arai <JCA02266@...>
新井です。
[#16532] 定数の再定義 — Wakou Aoyama <wakou@...>
青山です。
[#16545] BigFloat — matz@... (Yukihiro Matsumoto)
まつもと ゆきひろです
At Sat, 23 Mar 2002 22:55:45 +0900,
At Sun, 24 Mar 2002 02:20:26 +0900,
In article <867ko3yyik.wl@archon.local.idaemons.org>,
At Sun, 24 Mar 2002 04:21:59 +0900,
In article <864rj7yljs.wl@archon.local.idaemons.org>,
At Sun, 24 Mar 2002 07:44:15 +0900,
In article <861yeazvtg.wl@archon.local.idaemons.org>,
At Sun, 24 Mar 2002 15:41:18 +0900,
けいじゅ@日本ラショナルソフトウェアです.
けいじゅ@日本ラショナルソフトウェアです.
At Tue, 2 Apr 2002 16:16:04 +0900,
原です。
小林です。
[#16555] File.fnmatch (Re: [rubyist:1286] Re: ARGV の機能) — Koji Arai <JCA02266@...>
新井です。
In article <20020324.135631.115921076.JCA02266@nifty.ne.jp>,
新井です。
In article <20020324.143726.89024092.JCA02266@nifty.ne.jp>,
新井です。
[#16593] Oniguruma and multibyte character literal — TAKAHASHI Masayoshi <maki@...>
高橋征義です。
まつもと ゆきひろです
なかだです。
[#16609] control uid/gid — nagai@...
永井@知能.九工大です.
[#16633] socket.c/sock_addrinfo() — WATANABE Tetsuya <tetsu@...>
渡辺哲也です。
[#16636] -L for iconv — Tanaka Akira <akr@...17n.org>
FreeBSD で --prefix つきで Ruby を install するときに、ext/iconv を使
[#16652] [OniGuruma] nested repeat operator — "K.Kosako" <kosako@...>
[ruby-talk:36959]で指摘された
なかだです。
なひです。
なかだです。
なひです。
なかだです。
まつもと ゆきひろです
In article <20020329022810.68F9E17@helium.ruby-lang.org>,
Tanaka Akiraさんの<hvohemzoku6.fsf@coulee.a02.aist.go.jp>から
In article <20020329090116.832F4807@helium.ruby-lang.org>,
Tanaka Akiraさんの<hvod6xnohi8.fsf@coulee.a02.aist.go.jp>から
In article <20020402043641.5E1F6783@helium.ruby-lang.org>,
[#16697] assignment nil to $~ — Tanaka Akira <akr@...17n.org>
% ruby -e '$~ = nil'
まつもと ゆきひろです
In article <1017631490.892199.30753.nullmailer@ev.netlab.jp>,
[ruby-dev:16165] Re: autoload (Re: Re: : and ::)
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)
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
module Foo
class Bar
A = 1
end
end
puts "#{__FILE__} is loaded."
class Bar
A = 2
end
puts "#{__FILE__} is loaded."
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;
}