13

私は多かれ少なかれ次の設定をしています。には~/path/to/my/packagesと の 2 つのパッケージがpackage1.mありpackage2.mます。各パッケージの概要は、たとえば次のとおりです。

BeginPackage["package1`"]
Unprotect@@Names["package1`*"];
ClearAll@@Names["package1`*"];

Begin["`Private`"]

vecNorm[vec_?VectorQ]:=Module[{},Return[Sqrt[vec.vec]]];

End[]
Protect@@Names["package1`*"];
EndPackage[]

vecNormさて、私の問題は、 defined in package1.minを使用したいということですpackage2.mpackage1内から(安全に)ロードするにはどうすればよいpackage2ですか?

現時点では、次のように両方のパッケージを手動でロードします。

SetDirectory[StringJoin[NotebookDirectory[], "packages"]];
Needs["package1`"]
Needs["package2`"]

に保存されているノートブックから~/path/to/my手動でのみ ロードしたいのですが、package2これは自動的かつ安全にロードされますpackage1。一般的に、Mathematica のパスなどをできるだけ変更しないソリューションが必要です。これを達成するためのベストプラクティスは何ですか?

PS : 安全とは、将来、package3どちらが使用vecNormされ、ロードpackage1されるかを定義するときに、競合が発生しないことを意味します。

4

1 に答える 1

14

パッケージをロードするには、一般的に推奨される 2 つの方法があります。1つはいわゆるパブリックインポートで、あなたの設定では次のように行われます

BeginPackage["package2`",{"package1`"}]

(* Usage messages etc *) 

Begin["`Private`"]

(* code here *)

End[]
EndPackage[]

ここで、ロードするパッケージのコンテキスト名を の 2 番目のオプション引数であるリストに指定しBeginPackageます。$ContextPathこのインポート方法は、ロードされたパッケージがメイン パッケージがロードされた後も に残り、公開されるため、パブリックと呼ばれます。

2 番目の方法はプライベート インポートと呼ばれ、概略的に次のように行われます。

BeginPackage["package2`"]

(* Usage messages etc *) 

Begin["`Private`"]
Needs["package1`"]

(* code here *)

End[]
EndPackage[]

この方法では、ロードされた 2 番目のパッケージは、それをロードするパッケージ ( を使用Needs) でのみ使用できるため、プライベート インポートになります。

どちらの方法が必要かは、状況によって異なります。インポートを公開する必要がない限り、すべてのインポートを非公開にしようとします。ただし、デバッグの場合は、最初にパブリック インポートを作成すると便利な場合があります。これは、2 番目のパッケージをトップレベルで直接操作できるためです。

安全性については、パッケージを何個でもロードできるので安全です。複数のパッケージを同じコンテキストに同時にロードする場合、それらのパッケージに同じ短い名前のパブリック シンボルがない限り、これは安全です。そうしないと、シャドーイングの問題と呼ばれるものに遭遇しますが、それを回避するために必要な努力をするのが最善です (常に可能です)。

于 2011-12-05T12:38:24.667 に答える