6

プライベート関数を正しく定義する方法がわかりません。私がパッケージ数学を書いているとき、私はこれをするだけです:

BeginPackage["myPackage`"]
myPublicFunction::usage="myPublicFunction blahblahblah";
Begin["Private"]
myPrivateFunction[input_]:= ... ;
myPublicFunction[input_]:= ... ;
End[]
EndPackage[]

これは正しい方法ですか、それとも何かが足りませんか?

4

1 に答える 1

13

うん、それは正しい方法です。内部パッケージの仕組みのいくつかを理解することは報われるかもしれません。Mathematicaコンテキストは、他の言語の名前空間に似ています。それらはネストできます。すべてのシンボルは、あるコンテキストに属しています。いつでも、あるコンテキストは「現在」です。新しいシンボルが作成されるたびに、システムはそのシンボルがどのコンテキストに属するかを決定する必要があります。これは解析時に発生します。ここでの基本量(変数)はです$ContextPath。これは基本的にシンボルの検索パスです。これはコンテキストのリストであり、システムが新しいシンボルを検出するたびに、同じ短い名前のシンボル(つまり、コンテキストなしの適切なシンボルの名前)がのコンテキストに存在するかどうかをテストします。$ContextPath。それが存在する場合、シンボルの特定のオカレンスはその既存のシンボルに関連付けられます。そうでない場合、シンボルは現在のコンテキストで作成されます。これは動的なものであることに注意してください。$ContextPathいつでも変更すると、次のシンボルの出現を別のシンボルに関連付けることができます。

とにかく、BeginPackageそれは単に$ ContextPathの現在の値を{youPublicPackageContext, "System'"}、に加えて、の2番目のオプションの引数を介してパブリックにインポートする追加のコンテキストに置き換えるだけですBeginPackage。したがって、「パブリック」セクションにあるすべてのシンボルは、「システム」またはインポートする他のコンテキストにない場合、パブリックコンテキストに解析されます。そして、何をするかというと、パッケージのロードを開始する前EndPackageの値に復元することです。$ContextPathしたがって、技術的には、使用法メッセージは、メインコンテキストでシンボルを公開する唯一の方法ではありません。たとえば、セミコロンを使用してシンボルを入力することもできますmyFunction;(この方法はお勧めしません。メカニズムを明確にするために言及しました)。 。さて、あなたが入るとどうなりますかBegin["'Private'"]現在のコンテキストがYourContext'Private'(サブコンテキスト)になるということです。は$ContextPath変更されません。したがって、パブリックパッケージまたは他のインポートされたパッケージ(つまり、現在にあるコンテキスト)に存在しない、そこに入力されたシンボルは$ContextPath、自動的にサブコンテキストに解析され'Private'ます。

これらのシンボルを実際にプライベートにするのは、パッケージを他のコンテキスト(パッケージ)にインポートするたびに、メインパッケージのみがに追加され、$ContextPathサブパッケージには追加されないことです。YourPackage'Private'技術的には、$ ContextPath(たとえば)に手動で追加することでカプセル化を解除できPrependTo[$ContextPath, YourPackage'Private']ます。そうすると、インポートを行う特定のコンテキストで、すべてのプライベート関数とその他のシンボルがパブリックになります。繰り返しになりますが、この方法はお勧めできませんが、メカニズムを説明しています。要するに、シンボルがどのように解析されるか、$ContextPath および$Context(現在のコンテキストの値を与える別のシステム変数)を使用した操作は、次のようなコマンドによって実行される場合、プライベートまたはパブリックの概念を完全に理解できるということです。BeginBeginPackage。別の言い方をすれば、原則として、、、のアクションをユーザー定義のコードでエミュレートすることBeginPackageBeginできEndますEndPackage。ここで動作する原則はほんのわずかであり(上記で概説しようとしました)、メカニズム自体は実際にはユーザーに非常に公開されているため、まれに、他の動作が必要になった場合に、$ContextPathとを使用した「カスタム」操作。Contextシンボル解析の非標準的な方法を保証し、したがって、「非標準」な方法でパッケージスケールのカプセル化を制御します。私はこれを奨励していません。メカニズムは実際には表面上で見られるよりもはるかに単純で、はるかに制御可能であることを強調するだけです。

于 2011-02-27T21:01:01.210 に答える