初出: 2007/03/07
最新: 2007/04/27
[3. D言語各論] に戻る
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();
}
}