2017-02-07 4 views
0

私は3つのファイルを持っています。例えば、私が試してみた:は独立して

$ ocamlc -a lib.ml -o lib.cma 
$ ocamlc -a lib.cma desk.ml -o desk.cma 
$ ocamlc desk.cma test.ml -o test.byte 

残念ながら、あなたはtest.mlを変更した場合Lib.myfunction()であることを、同じコンパイル手順は、うまく動作します。 Libtest.mlに公開されておらず、desk.mlにしか公開されないようにします。誰もこれを行う方法を知っていますか?どうもありがとう!

答えて

1

あなたはOCamlの-packメカニズムを探しているようです。これにより、pack.cmaライブラリのようないくつかのコンパイルユニットからpack.cmo(またはネイティブコンパイルではpack.cmx)を作成できますが、対応するpack.mliインターフェイスを持つことができるという利点もあります。 pack。あなたの例では、インスタンスのために持っている可能性があり:

- lib.ml -

let myfunction() = print_endline "Hello world" 

- liberty.ml -

include Lib 

- desk.mli -

(* No module Lib: Lib will not be seen outside of the pack. *) 

module Liberty: sig 
    val myfunction: unit -> unit 
end 

次にあなたが

とそれをコンパイルすることができます

これはサブモジュールLibertyだけを含むDeskというモジュールを提供します。もちろん、desk.mliを使用して、より詳細な制限を得ることができます。

module Lib: sig end 

module Liberty: sig val myfunction: unit -> unit end 

であなたは、このようLibから関数(;-P例の一つだけが)単一の隠蔽、空の署名とLibをエクスポートします。

+0

非常に感謝しています! – Kites

0

あなたはLibがが使用できるモジュールdesk.cmaであることを要求していますが、他のモジュールは使用できません。私は、CMAファイルの構造がこの種の制御を提供していないと確信しています。

LibDeskに定義すると、非表示にすることができます。

$ ls 
desk.ml desk.mli test1.ml test2.ml test3.ml 

$ cat desk.ml 
module Lib = struct 
    let myfunction() = print_endline "Hello world" 
end 
module Liberty = Lib 

$ cat desk.mli 
module Liberty : sig 
val myfunction : unit -> unit 
end 

$ cat test1.ml 
Desk.Liberty.myfunction() 

$ cat test2.ml 
Lib.myfunction() 

$ cat test3.ml 
Desk.Lib.myfunction() 

リバティーモジュールはテストプログラムに表示されますが、Libのモジュールがありません:

$ ocamlc -c desk.mli 
$ ocamlc -a desk.ml -o desk.cma 
$ ocamlc desk.cma test1.ml -o test1.byte 
$ ./test1.byte 
Hello world 
$ ocamlc desk.cma test2.ml -o test2.byte 
File "test2.ml", line 1, characters 0-14: 
Error: Unbound module Lib 
$ ocamlc desk.cma test3.ml -o test3.byte 
File "test3.ml", line 1, characters 0-19: 
Error: Unbound module Desk.Lib 

あなたは別のファイルにLibのを実装することができ、その後、includeそれはDesk.Libの定義にモジュール。

これは完全に満足のいく回答ではないと思われますが、それが役に立ちそうです。

関連する問題