パッケージ
代表的な Mathematica パッケージにおいて新規に生成されるシンボルは2種類ある.そのひとつは,パッケージ外部への送出(エキスポートと呼ぶ)に使われるシンボルで,もうひとつは,パッケージ内部だけで使われるシンボルである.2つを区別するには別々のコンテキストを指定する必要がある.
デフォルトで,外部送出用のシンボルは,
という名前のコンテキストに入れられる.パッケージの読込み時にこのコンテキストが自動的に検索パスに付け加えられ,それを参照するには簡略名だけでよくなるようになっている.
また,内部処理だけで使うシンボルはプライベートなコンテキスト
に導入される.このコンテキストは検索パスには追加されない.このため,シンボルの参照には正式名を使う必要がある.
| Package` | 外部送出用パッケージのシンボルを導入するコンテキスト |
| Package`Private` | 内部処理用パッケージのシンボルを導入するコンテキスト |
| System` | 組込みシンボルのあるコンテキスト |
| Needed1`, Needed2`, ... | パッケージで必要な他のコンテキスト |
パッケージからコンテキストを設定するための命令書式および手順がある.それらを使い,現行コンテキスト$Contextと検索パス$ContextPathを適切に設定することで,新規シンボルを必要なコンテキストに導入できる.
| BeginPackage["Package`"] | パッケージ名 |
| f::usage="text", ... | 外部送出用オブジェクトを作成する |
| Begin["`Private`"] | 現行コンテキストを |
| f[args]=value, ... | パッケージの定義式本体を記述する |
| End[] | 定義記述を終えて,コンテキストを |
| EndPackage[] | パッケージコンテキスト |
BeginPackage["Collatz`"]
Collatz::usage =
"Collatz[n] gives a list of the iterates in the 3n+1 problem,
starting from n. The conjecture is that this sequence always
terminates."
Begin["`Private`"]
Collatz[1] := {1}
Collatz[n_Integer] := Prepend[Collatz[3 n + 1], n] /; OddQ[n] && n > 0
Collatz[n_Integer] := Prepend[Collatz[n/2], n] /; EvenQ[n] && n > 0
End[ ]
EndPackage[ ]
パッケージの最初の部分で
メッセージを定義するのが,エキスポートしたい記号が適切なコンテキストで作られていることを確実にする一般的な方法である.このメッセージを定義することで,そこで挙げた記号のみがエキスポートしたい記号となる.この記号はその時点で現行の
で作られる.
パッケージでは通常数多くの関数定義を行い,そのためパラメータや一時変数等の各種シンボルを導入しておく必要がある.これらのシンボルはデフォルトでパッケージのプライベートコンテキスト
に入れておくことになっている.なお,パッケージ読込みの際は,プライベートコンテキストは検索パスへ追加されない.
| In[1]:= |
| In[2]:= |
| Out[2]= |
| In[3]:= |
| Out[3]= |
のパッケージでは,定義する関数はすべて組込み関数に依存するだけである.しかし,場合によっては,他のパッケージにある関数を呼び出すものを作らなければいけないときもある.
そのときは,2つのステップを踏む必要がある.その第1ステップでは,必要な関数の存在する別のパッケージを読み込ませる.そして,第2ステップで,関数の定義されているコンテキストを検索パスに追加する.
現行セッションのどこでも,
の命令書式を使い必要なパッケージを読み込ませることが可能である.(パッケージファイルにアクセスする上で Mathematica コンテキスト名をシステムに依存したファイル名に変換する必要がある.詳しくは「パッケージのファイル」を参照のこと.)ただし,必要なときだけ自動的にパッケージが読み込まれるようになるとより便利である.Needs["context`"]と呼ばれる機能が提供されているので,それを使い必要なコンテキストを指定しておく.すると,そのコンテキストが現行パッケージのリスト$Packagesになければ,パッケージが自動的に読み込まれる.
| Get["context`"] または <<context` | コンテキストに対応したパッケージを読み込む |
| Needs["context`"] | コンテキストが現行パッケージリスト$Packagesになければ対応したパッケージを読み込む |
| BeginPackage["Package`",{"Needed1`", ... }] | |
| システムコンテキスト | |
BeginPackage["Package`"]を使うとき,パッケージ名の引数だけを与えると,組込みシンボル用のコンテキストの他には,
のコンテキストしか検索パスに追加されない.もし,ユーザの作成するパッケージに別のパッケージの関数に依存する定義式があると,そのパッケージのコンテキストも検索パスに加えておかなければいけない.それをするには,BeginPackageの命令に第2の引数として必要なコンテキスト名をリスト形式で列記する.すると,BeginPackageはNeedsの機能を自動的に使いコンテキストの作成に必要なパッケージを読み込み,検索パスに必要なコンテキストを加える仕組みになっている.
Beginのようなコンテキスト操作の命令を実行すると,ユーザの入力するシンボル名の解釈が変わる.ただし,変更は命令の後に続く式から有効になる.Mathematica では,式は一括で読み込まれるので,式の部分評価が始まる前に,式にあるシンボルの参照名がすべて解釈されることになっている.このため,式にBegin命令があっても,命令が実行される前に式の参照名が先に解釈されてしまう.つまり,Begin命令を使ってもその場ではコンテキスト変更の効果は得ることができない.
このようにコンテキストの操作命令は次の式が読み込まれるまで効力を発揮しないので,パッケージで使う際は,命令文だけを単体で別行に入力することが必要である.
コンテキストの操作命令は主にパッケージの読込みで使うものである.ただし,場合によっては計算を進める上で対話的に使うと便利なときもある.
パッケージにある関数を実行する際は,TraceDialogを使うと対話モードでコンテキスト命令が使える.関数の使う引数や一時変数は,通常,パッケージのプライベートコンテキストにある.このコンテキストは検索パスには指定されてないので,引数や変数は正式名で表示される.また,それらを参照するには正式名を使う必要がある.そこで,ダイアログを設け,Begin["Package`Private`"]の命令を実行すればパッケージのプライベートコンテキストを現行のものにできる.そして,引数等の表示では簡略名が使われるようになり,参照するにも簡略名だけでよくなる.
