ページ

2012年2月3日金曜日

ruby 拡張ライブラリのクラス定義の一部をrdocが認識してくれない時のメモ そ の2

以前書いた、C++コードで書いたruby wrapperのrdocに関する話の続き。

同じファイルに
ogre = rb_define_module_under(mg, "Ogre");
klass_= rb_define_class_under(ogre, "AnimationBlender", rb_cObject);

と書いていたものを、別々のファイルに置いて
-- fileA.cc ---
ogre = rb_define_module_under(mg, "Ogre");
AnimationBlenderWrapper::init(ogre);
----------------

--- fileB.cc ---
void
AnimationBlenderWrapper::init(VALUE module) {
klass_= rb_define_class_under(module, "AnimationBlender", rb_cObject);
}
-----------------

とした途端、
Enclosing class/module 'module' for class AnimationBlender not known
と言われた時のメモ。

rdocのcのパーサ(c.rb)のmoduleやclassの認識で気をつけておくべき点は以下3つ。

  1. moduleやclassの定義は、その名前と返り値を格納した変数名がセットで覚えられている。なにを言っているのか自分でもよく分からないが、つまり
    ogre = rb_define_module_under(mg, "Ogre"); と記述した場合。
    "Ogre"と言う名前と"ogre"という返り値がまずセットで覚えられる。

  2. class定義などで指定する上位class/module objectのVALUE変数名は、1の返り値を格納した変数名と同じである必要がある。klass_= rb_define_class_under(module, "AnimationBlender", rb_cObject);と書くと、rdocは上位のclass/module名を特定するために"module"という変数名とセットになっている名前を探しに行く。該当する変数名に返り値を格納した定義が無いとそのセットは記録されていないので、上記のようなエラーになる。正しく認識させるためには
    --- fileB.cc ---
    AnimationBlender::init(VALUE ogre) {
    klass_= rb_define_class_under(ogre, "AnimationBlender", rb_cObject);
    }
    -----------------

    として、そのclass/moduleを定義した時の変数名と一致させる必要がある。

  3. パーサは、判断を先送りにはしない男らしい設計
    上記を対処しても、fileA.ccより、fileB.ccを先にパーサが読み込んでしまうと
    Enclosing class/module 'ogre' for class AnimationBlender not known
    と言われる。なので
    rdoc   fileA.cc fileB.cc
    と順序性を指示してあげる必要がある。

0 件のコメント:

コメントを投稿