長い文字列を埋め込むために いろいろ迷走した が、コンパイル時にファイルから文字列を読み込む方法があることに気づいたので詳しく調べる。

Import Expression というのがある。 モジュールのimportとは違うものである。
import( <コンパイル時に決まる文字列定数> )と書くと、文字列をファイル名と解釈しその中身を文字列として取り込む。 Cのincludeで変数に文字列を入れられるのと同じである。

$ tree
.
├── resources
│   └── test.txt
└── test.d

1 directory, 2 files
//$ cat test.d
import std.stdio;

void main()
{
    writeln(import("test.txt")); // resources/test.txtの中身を出力
}
$ cat resources/test.txt 
this is test

セキュリティ上の理由により-Jスイッチでインポートするファイルの場所を指定してやる必要がある。これは複数指定できるらしい。

$ dmd test.d -Jresources
$ ./test
this is test

dubでも同じことが出来る。 デフォルトではviewsフォルダを指定した状態になっているが、 stringImportPaths でフォルダを変更することもできる。

$ tree
.
├── dub.json
├── source
│   └── app.d
└── views
    └── test.txt

2 directories, 3 files
//$ cat source/app.d 
import std.stdio;

void main()
{
    writeln(import("test.txt"));
}
$ cat views/test.txt 
this is test
$ dub run
Performing "debug" build using dmd for x86_64.
test ~master: building configuration "application"...
Linking...
Running ./test
this is test

とても便利。 たとえばD言語くんのAAを使う時とかに使える。

続き: importでコンパイル時にファイルを埋め込む