From: Koji Arai Date: 1999-12-08T01:14:07+09:00 Subject: [ruby-dev:8588] [BUG?] autoloading class (Re: [PATCH] Ruby/Tk and ...) 新井です。 自分で完全に忘れてたのですが、以下の件どう思いますか? >>> From: Koji Arai >>> Date: 30 Nov 1999 00:52:54 +0900 >>> Subject: [ruby-dev:8445] [PATCH] Ruby/Tk and ... > 新井です。 > で、ちょっと質問です。上記バグを確認しようと思っていろいろやっ > てたらよくわからない点がでてきたので。 > > $ head -999 hoge* > ==> hoge.rb <== > autoload :Hoge, "hoge2.rb" > require "hoge2.rb" > > class Hoge > def hoge > end > end > p Hoge.instance_methods > > ==> hoge2.rb <== > class Hoge > def hoge2 > end > end > > 上記スクリプト(hoge.rbの方)を実行すると > > $ ruby -v hoge.rb > ruby 1.4.3 (1999-11-24) [i586-linux] > hoge.rb:7: warning: already initialized constant Hoge > ["hoge"] > > となります。["hoge", "hoge2"]を期待してたわけですが・・・ 実例を出した方がわかりやすいと思うので、例えばautoload 対象 のクラスにメソッドを追加したい場合に require "tk" class TkAfter def inspect @id end end p TkAfter.instance_methods などとやるとメソッド追加ではなくクラス定義になります。これは 直感に反しますよね。ライブラリ利用者にとってautoload なクラ スかどうかなんて関係ないはずですから。 とりあえず添付のパッチで回避できたのですが、今度は require "tk" require "tkafter" などとするとエラーになります(なるほどパッチで削った箇所はそ ういうチェックだったのか)。 /usr/local/lib/ruby/1.5/tkafter.rb:296: uninitialized constant TkAfter (NameError) ちょっと簡単に回避する方法を思いつかなかったので、今日はここ まで。 --- eval.c.org Tue Dec 7 23:33:41 1999 +++ eval.c Tue Dec 7 23:49:52 1999 @@ -2799,8 +2799,7 @@ } klass = 0; - if (rb_shvar_defined_at(ruby_class, node->nd_cname) && - (ruby_class != rb_cObject || !rb_autoload_defined(node->nd_cname))) { + if (rb_shvar_defined_at(ruby_class, node->nd_cname)) { klass = rb_shvar_get(ruby_class, node->nd_cname); } if (ruby_wrapper && rb_shvar_defined_at(rb_cObject, node->nd_cname)) { @@ -2852,9 +2851,7 @@ rb_raise(rb_eTypeError, "no outer class/module"); } module = 0; - if (rb_shvar_defined_at(ruby_class, node->nd_cname) && - (ruby_class != rb_cObject || - !rb_autoload_defined(node->nd_cname))) { + if (rb_shvar_defined_at(ruby_class, node->nd_cname)) { module = rb_shvar_get(ruby_class, node->nd_cname); } if (ruby_wrapper && rb_shvar_defined_at(rb_cObject, node->nd_cname)) {