[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dennou-ruby:000981] Re: AdvancedDCL-0.1.8 Install Memo



堀之内です。

>     mNum = rb_define_module("NumRu");
> 
> で、モジュール定義してますが、どうやら Ruby プログラム内のように
> 追加にならず、上書きになるようです(ところで、これはグローバル変
> 数なんだから NumRu --> mNumRu を勝手に縮めて mNum とするのは大変
> まずい!)。 ためしに一方をコメントアウトしたら問題なく動きまし
> た。でもそれじゃ使えないので、条件判断しないとならないですね。
> 
> Ruby のパーサーはほんとにそれをしてるんだろうか??

実験しました。ほんとです。

Rubyソースでは rb_define_module は名前を id に変換して 
rb_define_module_id を呼んでます。Ruby プログラムを処理する
eval.c ではこの rb_define_module_id を呼んでますので、その直前に
printf を入れてみて確認しました。その結果、以下のように、module
定義文を何回か呼んでも、rb_define_module_id は一回しか呼ばれない
ことがわかりました。

module Helo
   print "a\n"
   def a
   end
end
module Helo
   print "a\n"
   def b
   end
end

よって、教訓は、「拡張ライブラリーでは rb_define_module は、ほん
とに再定義になる」ということです。恐らく ruby のパーサーが定数の
再定義の禁止則により、モジュールの定義を行わずにスコープだけ切り
替えるのでしょう。

根本原因がわかりましたので、RubyNetCDF, RubyDCL の改訂を行います。

堀之内