新井です。

自分で完全に忘れてたのですが、以下の件どう思いますか?

>>> From: Koji Arai <JCA02266 / nifty.ne.jp>
>>> 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)) {