3-b8. flectioned でリフレクション

初出: 2007/03/07
最新: 2007/04/27
[3. D言語各論] に戻る

flectioned とは

flectioned とは、 D言語に実行時リフレクションの機能を付け加えるライブラリです。

「文字列でクラス名を指定してそのオブジェクトを作る」 「文字列で関数名を指定して関数ポインタを取得」 「関数ポインタを渡すとその関数の名前を取得」 などができるようになります。ちょっと動的言語っぽくなります。 flectioned を使うことで、「例外発生時にスタックトレースを表示」 「全モジュールのunittestを起動して回る」など、 主にデバッグにものすごく便利な機能が手に入ります。

インストール方法

トップページの最下部から、 flectioned.zip をダウンロード&展開します。

リフレクションしたいプログラムと一緒にビルドして使う使い方を想定されているみたいです。 main.d でリフレクションしたければ、

main.d
cn/kuehne/flectioned.d

というファイル配置にして(flectioned.d は zip 書庫に入っているものです。ch/kuehne ディレクトリは自分で作成すること)

dmd -g main.d cn/kuehne/flectioned.d

あるいは

bud -g main.d

とコンパイルして使います。bud を使う場合、dmd や gdc の -I の通ったところに cn/kuehne/flectioned.d を置いておくのでも構いません。 コンパイルオプションは、Windows以外では-gなしでも大丈夫です。 Windows では -g をつけないと動きません。

(標準で添付されているphobos.libは-gなしでコンパイルされているため、 実はうまくリフレクションが効きません。phobosを-gつきでコンパイルし直すのが 推奨されています。)

使い方

とにかく便利なのが、例外のスタックトレース表示です。

import cn.kuehne.flectioned;
static this()
{
    TracedException.traceAllExceptions();
}

void g(char x, float y)
{
    char[] t = null;
    t[1] = 'a';
}

void f(int n)
{
    if(n) f(n-1);
    else  g('x', 2.0);
}

void main()
{
    f(1);
}

Java などでは当たり前の機能ですが、D でも、flectioned の TracedException.traceAllExceptions を呼んでおけば

> bud -g test.d
> test
Error: (std.array.ArrayBoundsError) ArrayBoundsError test(6)
        0x0012FEF4      0x00409D6A      object.Error object.Error._ctor(char[],this)
        0x0012FF08      0x0040202A      void test.g(char, float)
        0x0012FF1C      0x0040205D      void test.f(int)
        0x0012FF28      0x0040204E      void test.f(int)
        0x0012FF30      0x00402074      int main(char[][])
        0x0012FF80      0x00407010      extern(C) int main(int, char**)

これが出るようになります。超絶便利です。

その他いろいろな使い方は、 公式ページのSamples がわかりやすいので掴めると思います。

※追記 2007/04/27現在(dmd 1.014)、dmd側の仕様変更で、 上のコードではスタックトレースがでなくなってしまいました。 以下のように、明示的にcatch&表示してやると同じスタックトレースが取れます。

void main()
{
    try {
        f(1);
    } catch( Exception e ) {
        e.print();
    }
}

[3. D言語各論] に戻る

presented by k.inaba   under NYSDL.