From: Nobuyoshi Nakada Date: 2007-02-27T11:00:40+09:00 Subject: [ruby-dev:30434] Re: fail to autoload at $SAFE==4 なかだです。 At Mon, 26 Feb 2007 00:50:48 +0900, Hidetoshi NAGAI wrote in [ruby-dev:30419]: > > > $SAFE==0 などで autoload が適切に設定されている場合, > > > $SAFE の値に無関係にきちんと load されるべきと思いますし, > > > 事実,これまではそのように働いていたのですが, > > > 20070219 の commit の結果,うまく機能しないようになっています. > > > > すいません。これでどうでしょう。 > > ありがとうございます.動くようになりました. > ruby_1_8 および ruby_1_8_6 への commit をよろしくお願いいたします. 現在のコードがsearch_required()を呼ぶようになっている理由は、 requireは拡張子が指定されていなければ.rb, .soなどを探すという仕 様だからです。つまり、もしすでに拡張ライブラリがロードされてい たとしても、$LOAD_PATH中におなじfeature名の. rbファイルがあれ ば、そちらが優先されるためにrb_provided()はfalseを返さなければ なりませんが、前回のパッチでは拡張ライブラリとスクリプトライブ ラリの両方がある場合には対応できません。 ということで考えたのが、以下の二つの案です。 (1) safe_levelを指定して探してくれるrb_provided()を追加する (2) rb_provided()は拡張ライブラリについてはあきらめる rb_provided()はautoload関連でしか使われていないので、とりあえず は(2)でいいのではないかと思います。拡張ライブラリだけロードされ た時点では未定義の定数がdefined?やautoload?で真を返すようになり ますが、実際に参照されればconst_missingになるので、許容範囲では なかろうかと。 Index: eval.c =================================================================== --- eval.c (revision 11898) +++ eval.c (working copy) @@ -6938,4 +6938,7 @@ static const char *const loadable_ext[] }; +static int rb_feature_p _((const char *, const char *, int)); +static int search_required _((VALUE, VALUE *, VALUE *)); + static int rb_feature_p(feature, ext, rb) @@ -6974,5 +6977,5 @@ rb_feature_p(feature, ext, rb) if (loading_tbl) { if (st_lookup(loading_tbl, (st_data_t)feature, 0)) { - if (ext) return 'u'; + if (!ext) return 'u'; return strcmp(ext, ".rb") ? 's' : 'r'; } @@ -6994,19 +6997,22 @@ rb_feature_p(feature, ext, rb) } -static int search_required(VALUE, VALUE *, VALUE *); - int rb_provided(feature) const char *feature; { - VALUE fname, path; + const char *ext = strrchr(feature, '.'); - if (rb_feature_p(feature, 0, Qfalse)) - return Qtrue; - if (search_required(rb_str_new2(feature), &fname, &path) != 0) { - feature = RSTRING_PTR(fname); - if (rb_feature_p(feature, strrchr(feature, '.'), Qfalse)) - return Qtrue; + if (ext && !strchr(ext, '/')) { + if (strcmp(".rb", ext) == 0) { + if (rb_feature_p(feature, ext, Qtrue)) return Qtrue; + return Qfalse; + } + else if (IS_SOEXT(ext) || IS_DLEXT(ext)) { + return Qfalse; /* may be overriden by .rb file */ + } } + if (rb_feature_p(feature, 0, Qfalse) == 'r') + return Qtrue; + return Qfalse; } -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦