From: nobu.nakada@... Date: 2002-09-02T05:00:28+09:00 Subject: [ruby-dev:18140] Re: autoload patch for ruby-1.7 なかだです。 At Mon, 2 Sep 2002 02:38:22 +0900, Yoshinori K. Okuji wrote: > > 確かめたわけじゃありませんが、ファイル名とシンボルの配列をキー > > にするよりも、st_tableを各モジュールに持たせたほうが速いような > > 気がします。 訂正。モジュールとシンボルの配列でした。 > 実を言うと、中田さんのパッチにも私のパッチにも、というか、元の師星さん > のパッチに、非互換性の問題が一つ、重大なバグが一つあります。非互換なの > は、オリジナルでは、 > > autoload :Foo, "foo.rb" > autoload :Foo, "bar.rb" > p Foo > > とした時、bar.rbがロードされるのに対し、パッチではfoo.rbがロードされて > しまいます。これは簡単に直せると思います。 あ、確かに。このへんはあまり考えてませんでした。 > バグの方ですが、 > > autoload :Foo, "foo.rb" > autoload :Bar, "foo.rb" > p Foo > p Bar > > のように、一つのファイルに複数の定数が定義されているとき、それぞれに > autoloadを呼ぶと、一つ目は成功しますが、それ以降は失敗することです。こ > れはautoload_deleteが実際のロードのきっかけになった定数しかst_deleteし > ないことが原因だと思います。 失敗はしないと思います。warningは出ますが。 $ ./i686-linux/miniruby -e 'autoload :Foo, "foo.rb"' -e 'autoload :Bar, "foo.rb"' -e 'p Foo' -e 'p Bar' ./foo.rb:2: warning: already initialized constant Bar 1 2 > それなり速くて素直なのは、逆方向のハッシュテーブルを別に持ち、あるファ > イルからautoloadされるべき定数のリストを簡単に見られるようにしておく方 > 法です。この方法を使うと、データを重複して持たないといけなくなるので、 > あんまり良くないかもしれません。 > > 少々遅くても良いなら、テーブルを全検索して、同じファイルからロードされ > る定数を見付ける方法もあります。これだとautoloadされる定数が1000とかに > なると(そんなことはあり得ないとは思いますが)、すごく遅いと思います。 > > あまり良いアイディアが浮かばないので、代案をいただけるとありがたいです。 手抜きですが、autoload定数は上書きしてもwarningを出さないように するとか。 --- variable.c~ Sun Sep 1 23:43:30 2002 +++ variable.c Mon Sep 2 04:58:47 2002 @@ -1056,5 +1056,5 @@ rb_mod_autoload(mod, sym, file) Check_SafeStr(file); - if (rb_const_defined_at(mod,id)) + if ((tbl = RCLASS(mod)->iv_tbl) && st_lookup(tbl, id, &av) && av != Qundef) return Qnil; @@ -1416,6 +1416,8 @@ mod_av_set(klass, id, val, isconst) 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); - rb_warn("already initialized %s %s", dest, rb_id2name(id)); + if (value == Qundef) + autoload_delete(klass, id); + else + rb_warn("already initialized %s %s", dest, rb_id2name(id)); } } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦