libオブジェクト
他のファイルに書かれたライブラリを読み込みたい。
(Cでいうinlcude、Rubyでいうrequire、Pythonでいうimportがしたい)
そんな時には libオブジェクト を使います。
libオブジェクトは特殊なオブジェクトで、lib::foo とアクセスした場合、foo.xtalを読み、そこでexportされた値を返す機能を持ってます。
// foo.xtal export "文字列をexportしました";
// test.xtal foo : lib::foo; // ここでfoo.xtalがコンパイルされ、実行される println(foo); // => 文字列をexportしました
lib::fooと書けばその度に何回もコンパイル、実行されるわけではなく、最初の実行で値は保存されるため、2回目以降は保存された値が返ります。
組み込み関数でload関数が用意されているので、それを使えば何度でもコンパイル、実行ができます。
load("foo.xtal");
libオブジェクトは階層にも対応しています。
// folder/bar.xtalをコンパイル、実行してexportされた値を取り出す bar : lib::folder::bar;
また、libオブジェクトにプログラムから登録することもできます。
登録の構文は、クラスやモジュールにメンバを追加定義するのとまったく同じです。
lib::hoge : "register"; // lib::hogeはもう格納されているため、hoge.xtalファイルは探されない println(lib::hoge); // => register // error! classやmodule同様、libオブジェクトも再定義を認めない lib::hoge : "once more"; // 次の文はそもそもコンパイルできない。代入の左辺にメンバ参照式は許可されない。 // lib::hoge = "once more";
libがファイルの検索を開始するパスは builtin::lib_path に配列として格納されています。
ここにパスを追加すれば、そのパスも検索対象となります。
lib_path.push_back("c:/hoge/huge"); println(lib_path.join(", ")); // => ., c:/hoge/huge
この状態で lib::foo と書くと
./foo.xtal、 c:/hoge/huge/foo.xtalと検索されて、最初に見つかったものがコンパイル、実行されます。