2012-04-02 5 views
7

OCaml(主にユーティリティとヘルパー関数)にいくつかの "ライブラリ"モジュールがあります。最後に、簡単なユニットテストのために次のようなコードを追加しました:リンクされたOCamlモジュールの複数の "mains"

let main() = ... 
main 

又は

let() = ... 

(単純なテスト目的のために)コンソールへ主プリントこのビーイング・コード。問題は、今私の "ライブラリ"モジュールを私の "メイン"モジュールにリンクしてプログラムを実行すると、これらの気を散らすテストメッセージがすべて得られるということです。モジュールが単独でリンクされたときに実行されるOCamlモジュールにコードを含める方法はありますか(つまり、簡単なテストを容易にする)が、「ライブラリ」として使用する場合はそうではありませんか?私はOCamlに "main"モジュールの概念がなく、すべてのモジュールが同じだと言うわけではないので、SOの記事を読んでいますが、リンカに与えられたオブジェクトファイルの順序が、最後のモジュールは "メイン"モジュールです(それは "依存関係のフードチェーン"の最上位にあるためです)。

答えて

7

OCamlはモジュールの静的リンクと動的ロードをサポートしています。あなたが普通にやっていること(そしてタイプセーフなもの)は静的リンクです。私はプラグインのアーキテクチャのいくつかの種類が必要な場合のみ動的ロードをお勧めします。

とにかく、ライブラリはモジュール以外の何ものでもありません(おそらくサブモジュールがあります)。 モジュールを静的にリンクすると、実行可能ファイルにリンクされているモジュールの順番に、すべての「メイン」ルーチンが実行されます。

もし何もしないのであれば、モジュールはリンクされている実行可能ファイルを「魔法のように」知りません。あなたは私見やるべきことは次のとおりです。モジュールのうち

  • 移動テストでは、おそらくounit OR
  • を使用して
  • 少なくとも例えば実関数であるようにテスト関数を書き換えます"let test()= ...";すべてのモジュールからすべての "test"関数を呼び出すテストフロントエンドを記述します。

補遺:

あなたが他の言語で、空きケーキはないように思われることを行う場合は、次のいずれか

Javaでは、あなたはあなたのコード内に複数の電源を持っている場合は、あなたが明示的に指定する必要があり実行可能ファイルを実行するファイルを選択します。

はCでは、

#ifdef TEST_1 
int main() { 
... 
} 
#endif 

OCamlはあなたが似た何かをする可能性があるとの独自のプリプロセッサcamlp4camlp4 wikipedia article)を持っているような何かをするためにCプリプロセッサを使用することができます。 私は個人的にこの種のテスト埋め込みを悪いソフトウェアエンジニアリングとみなしています。インターフェイス側からモジュール/クラス/ ..をテストし、内部のインバリアントをアサーション(Javaに存在する、C & OCaml)でマークする必要があります。

+0

Cでは正しいですが、テストフロントエンドを使う必要がありますが、Javaでは、自明ではないクラスのmain()に何らかの大雑把な "テスト"をさせるのが一般的です。ある種類のコードがクリーンアップされ、それ以上の目的を果たさないテストフレームワークですが、最初のアクティブな開発中にこの機能が使用されます。私はOCamlではトップレベルを持っているが、同じことではないことを認識しています。 –

+0

コメント:addendumをご覧ください – lambdapower

5

ツールチェーンにはこれに関する規定がありません。リンクする順番に、起動時にすべてのモジュールの最上位コードを実行するファイルを生成します。

私はそれを体系的に機能させる方法は見当たりません。モジュールには、ほとんどの場合、実行する必要があるいくつかの最上位コードがあります。トップレベルコードを2つのグループに分ける方法が必要です(1つのグループは常に実行され、もう1つはモジュールが最後にリンクされたときにのみ実行されます)。これは不必要に乱雑です。

もっと良い解決策(それは私のようです)はちょっとだけ洗練されたテストフレームワークを使用することです。

関連する問題