xtal を試してみた その7
xtal で ruby でいうところの組み込みクラスを増やすにはどうしたらいいのか調べてみました。
試しに Dir クラス(xtal_dir.h および xtal_dir.cpp)を追加してみます。
Dir クラスについて
まだ必要な機能を実装していないのですが、以下のような感じで作ってみました。機能は 2 つです。
- インスタンスを生成できる
dir : Dir();
- to_s メソッドをコールすると「dir object」と標準出力へ出力する
dir.to_s.p;
//=>dir object
また、「#pragma once」が gcc で認識できることをはじめて知りました。(どうでもいいですね
// xtal_dir.h #pragma once #include "xtal_fwd.h" #include "xtal_base.h" namespace xtal { /** * @brief ディレクトリクラス */ class Dir : public Base { public: /** * @brief ディレクトリオブジェクトを生成します */ Dir(); /** * @brief デストラクタ */ ~Dir(); /** * @brief 文字列化します */ StringPtr to_s(); }; } // namespace xtal
// xtal_dir.cpp #include "xtal.h" #include "xtal_dir.h" namespace xtal { void InitDir() { ClassPtr p = new_cpp_class<Dir>("Dir"); p->def("new", ctor<Dir>()); p->method("to_s", &Dir::to_s); } Dir::Dir() { } Dir::~Dir() { } StringPtr Dir::to_s() { MemoryStreamPtr ret(xnew<MemoryStream>()); ret->put_s("dir object"); return ret->to_s(); } } // namespace xtal
手順 1: xtal/xtal.h へインクルード追加
まずはメインのヘッダファイルっぽいファイルである xtal/xtal.h へ xtal_dir.h のインクルード文を追加します。
$ svn diff xtal/xtal.h Index: xtal/xtal.h =================================================================== --- xtal/xtal.h (revision 123) +++ xtal/xtal.h (working copy) @@ -28,5 +28,6 @@ #include "xtal_thread.h" #include "xtal_ch.h" #include "xtal_stream.h" +#include "xtal_dir.h"
手順 2: xtal/xtal_base.cpp へ Dir クラス初期化関数コール追加
xtal_dir.cpp で定義した InitDir() 関数を呼び出すコードを xtal_base.cpp に追加します。
$ svn diff xtal/xtal_base.cpp Index: xtal/xtal_base.cpp =================================================================== --- xtal/xtal_base.cpp (revision 123) +++ xtal/xtal_base.cpp (working copy) @@ -21,6 +21,7 @@ void InitClass(); void InitStream(); void InitCode(); +void InitDir(); namespace{ @@ -114,6 +115,7 @@ new_cpp_class<Fiber>(); new_cpp_class<XClass>(); new_cpp_class<Lib>(); + new_cpp_class<Dir>(); InitDebug(); @@ -133,6 +135,7 @@ InitClass(); InitStream(); InitCode(); + InitDir(); atexit(&uninitialize); // uninitialize
手順 3: xtal/xtal_lib.cpp へ Dir クラスコンストラクタ紐付け
xtal_lib.cpp にて、builtin クラスと各クラスのコンストラクタの紐付けを行なっています。
ですので Dir クラスのコンストラクタも builtin クラスに紐付けます。
$ svn diff xtal/xtal_lib.cpp Index: xtal/xtal_lib.cpp =================================================================== --- xtal/xtal_lib.cpp (revision 123) +++ xtal/xtal_lib.cpp (working copy) @@ -917,6 +917,7 @@ builtin->def("Format", get_cpp_class<Format>()); builtin->def("Code", get_cpp_class<Code>()); builtin->def("Instance", get_cpp_class<Instance>()); + builtin->def("Dir", get_cpp_class<Dir>()); builtin->def("stdin", xnew<FileStream>(stdin)); builtin->def("stdout", xnew<FileStream>(stdout)); builtin->def("stderr", xnew<FileStream>(stderr));
この処理を追加し忘れると xtal 側から Dir クラスが見えません。つまり以下の文が通らなくなります。(ここでハマりました)
ix:001>dir: Dir(); lib::builtin::UnsupportedError: filelocal :: 'Dir' is not defined member <ix>:1: in <instance of lib::builtin::Fun>
まとめ
現在の xtal は、システムへのアクセスを行なうクラス・メソッドが少なくてまだ実用段階じゃないと思いますが(意図的かも?)、これで機能追加の準備は整いました。