pkg_mkIndex -
パッケージをオートロードするためにインデックスを作成します。
pkg_mkIndex ?-direct? ?-lazy? ?-load pkgPat? ?-verbose?
dir ?pattern pattern ...?
Pkg_mkIndexは標準Tclライブラリの1部であるユーティリティ・プロシージャです。これはインデックスファイルを作成するために使われます。これによってpackage requireコマンドが実行されたときにパッケージが自動的にロードできます。
pkg_mkIndexを利用するには、次のステップに従います。
- [1]
- パッケージを作成します。各パッケージは、1つ以上のTclスクリプ
トファイルかバイナリファイルからなります。バイナリファイルは、1つの引数だけを持つloadコマンドでのローディングに適していなければなりません。例えば、ファイルがtest.soとすると、コマンドload
test.soでこのファイルをロードすることが可能でなければなりません。パッケージとバージョン番号を宣言するために、各スクリプトファイルは
package provide
コマンドを含んでいなければなりません。そして各バイナリファイルは
Tcl_PkgProvideを呼び出さなければなりません。
-
- [2]
- pkg_mkIndexを呼び出してインデックスを作成します。 dir 引数はディレクトリの名前を与え、各pattern
引数はdir内のスクリプトまたはバイナリファイルを示します。pattern
は globスタイルです。
デフォルトパターンは*.tcl また *.[info sharedlibextension ]です。
- Pkg_mkIndexはpattern 引数で与えられたすべてのファイルに関するパッケージ情報で、ファイル
pkgIndex.tclをdirに作成します。これは、各ファイルをサブインタープリタにロードし、どんなパッケージや新しいコマンドが使用されるかを検査することで実現します(これが上述、package
provideコマンドや Tcl_PkgProvide呼び出しが、ファイルに存在することがなぜ必要かの理由です)。
スクリプトとバイナリファイルで分割されたパッケージの場合、あるいはファイル間に依存関係がある場合、
-loadオプションを使うか、またはpkg_mkIndexがファイルを処理する順番を調整しなければなりません。
以下の複雑なケースを参照します。
- [3]
- tcl_pkgPath変数で与えられるディレクトリの1つのサブディレクトリとして、パッケージをインストールします。
$tcl_pkgPathが1つ以上のディレクトリを含む場合、通常マシン依存のパッケージ(バイナリの共有ライブラリを含む)は1番目のディレクトリ下にインストールすべきです。マシン独立のパッケージ(それらはTclスクリプトだけを含む)は2番目のディレクトリ下にインストールすべきです。
サブディレクトリには、pkgIndex.tcl ファイルと、パッケージのスクリプトまたはバイナリファイルを含みます。
パッケージが$tcl_pkgPath内のディレクトリのサブディレクトリにインストールされていればpackage
requireコマンドは自動的に見つけます。
- パッケージを他の場所にインストールすると、パッケージを含むディレクトリがauto_pathグロバール変数か、auto_path内のディレクトリの直下のサブディレクトリにあることを保証しなければなりません。
Auto_pathはディレクトリのリストを含みます。検索機能をもつauto-loaderとパッケージローダーの両方で検索されます。
ディフォルトでは$tcl_pkgPathを含みます。アプリケーションでauto_pathにディレクトリを明示的に追加することができます。TCLLIBPATH環境変数にディレクトリを追加することができます。
この環境変数が存在すればTclはアプリケーションのスタートアップ時にこの環境変数でauto_pathを初期化します。
-
- [4]
- いったん前述のステップが終ったら、パッケージを使用するためにpackage
requireを呼び出すことになります。例えば、もしパッケージTestのバージョン
2.1、 2.3、3.1がpkg_mkIndexでインデックスされていると仮定すると、コマンドpackage
require Testはバージョン3.1を利用可能にし、コマンドpackage
require -exact Test 2.1はバージョン2.1を利用可能にします。多くのパッケージのバージョンがauto_path
のさまざまなインデックスファイルにあるかもしれませんが、最初のpackage
require呼び出しに基づき、与えられたインタプリタに実際にロードされるのは1つだけです。バージョンが異なるパッケージが違うインタプリタにロードできます。
選択可能なオプションは以下です。
- -direct
- -lazy
- -load pkgPat
- -verbose
- --
- -direct
- 生成されたインデックスは、package requireでパッケージの直接ローディングを実行します。このオプションはデフォルトです。
- -lazy
- 直ちにpackage requireでパッケージをロードする代わりに、生成されたインデックスは、パッケージに提供されたコマンドの1つが使用されるまで、パッケージをロードすることをできるだけ遅延します。
- -load pkgPat
- インデックスプロセスは、現在のインタープリタに存在する全部のパッケージを予めロードし、そしてpkgPat
をインデックスを生成するのに使われるサブインタープリタへマッチします。パターンマッチはストリングマッチのルールを使います。
以下の複雑なケースを参照します。
- -verbose
- インデックスする過程に出力を生成します。出力はtclLogプロシージャを通
じてデフォルトで標準エラー出力(stderr)に書き出します。
- --
- dir がダッシュで始まる場合、フラグの終了を意味します。
パッケージ管理機能はauto-loaderの一部と重なります。要求に応じてファイルがロードされるよう手配するという部分です。但し、
パッケージ管理はより高いレベルのメカニズムで、ロード過程の最後のステップでauto-loaderを使用します。
pkg_mkIndexでパッケージをインデックスすることは、パッケージメカニズムがバージョン管理を提供するなら、一般
にauto_mkindexを使うより良い方法です。package
requireコマンドに基づき、異なるバージョンを使用する異なるアプリケーションとともに、パッケージの複数のバージョンがインデックスファイルの中で利用可能にできます。一方、auto_mkindex
はバージョンの概念がなく、このため各パッケージの単一のバージョンしか扱えません。
pkg_mkIndexとauto_mkindexの両方で、あるパッケージをインデックスすることは良い考えとはいえません。
pkg_mkIndex をパッケージをインデックスするために使用すると、
該当コマンドはバージョンを選択するためにpackage require
が使用されるまで呼び出すことができません。一方、auto_mkindex
でインデックスされたパッケージはバージョン管理がないので直ちに使用できます。
Pkg_mkIndexはpackage unknownコマンド、package ifneededコマン ド、
そしてオートローダに依存します。package
require コマンドが最初に呼ばれたとき、package
unknownスクリプトが呼び出されます。 これは、Tcl
の初期化によりすべてのauto_path内の pkgIndex.tclを評価するスクリプ
トに設定されます。 pkgIndex.tclファイルは各利用可能なパッケージの各バージョンのためのpackage
ifneededコマンドを含みます。 これらのコマンドは package provideコマンドを呼び出すパッケージが利用可能であることを公表するために、パッケージのファイルをロードするためのオートローダ情報をセットアップします。与えられたパッ
ケージのバージョンのファイルは、最初に1つのコマンドが呼び出されるまでは実際にはロードされなません。このため、package
requireの呼び出しの後でもパッケージのコマンドをインタプリタで見つけることはできません。
しかしそのコマンドを呼び出すことはでき、その時点でオートロードされます。
いくつかの特定な初期化を必要とするパッケージは(例えば、名前空間を使う、コマンドを公開する等)、パッケージファイルが最初の使用によって実際のローディングを延期する代りに、package
requireで直ちにロードされることを選択します。これはパッケージインデックスを生成するときのデフォルトモードです。それは-lazy
引数を指定することによってオーバライドされることができます。
スクリプトとバイナリファイル間の依存関係、及びスクリプトとバイナリファイルに分割されたパッケージなど、ほとんどの複合ケースがよく扱われるようになりました。しかし、ファイルがpkg_mkIndexによって処理される順番を調整しなければならないケースもあります。
これらの問題は以下で詳細に説明します。
各スクリプトまたはファイルが1つのパッケージを含み、そしてパッケージがただ1つのファイルに含まれる場合は容易です。単にいくらかのglobパターンを使って、全てのファイルはどのような順番でインデックスされるかを指定します。
一般的にスクリプトが他のパッケージに依存しても問題ありません。スクリプトがpackage
require
コマンドを含んでも、スクリプトを処理するために使われるインタープリタによってそれを消します。従って、これも問題を引き起こしません。
スクリプトがグローバルなコードにおける他のパッケージに呼びだされる場合、これらのコールはスタブ
unknownコマンドによって扱われます。しかし、スクリプトがグローバルなコードにおいて他のパッケージの変数への変数引用をするとエラーとなります。よくないコーディングスタイルです。
バイナリファイルが他のパッケージに依存することは、扱いにくいものです。なぜなら、バイナリファイルをロードするとき
Tcl_PkgRequireAPIのようなC‐レベルAPIをもみ消すことが出来ないからです。例えば、BLTパッケージがTkを必要とし、Blt_Initルーチンにおける
Tcl_PkgRequireのコールによって示されるとします。これをサポートするためにTkをロードされたインタープリタにおいてpkg_mkIndexを実行しなければなりません。これを-load
pkgPatオプションによって達成できます。
このオプションが指定されるとpkg_mkIndexが info
loadedによりリストされたpkgPatにマッチする全部のパッケージをファイル処理インタープリタにロードします。これはほとんどのケースでバイナリファイルに呼び出されたTcl_PkgRequireコールを満たします。
2つのバイナリファイルがインデックスされるとき、1つがもう一方に依存すれば、最後に依存を持つものを指定する必要があります。このように依存なしのものはロードされインデックスされます。そして2番目のファイルが処理されるときそれが提供するパッケージは利用可能です。
また、-loadフラグを利用することによってインデックスを作成するために使われる一時的なインタープリタに最初のパッケージをロードする必要があるかもしれません。まだロードされないパッケージパターンを指定することは問題ないです。
スクリプトとバイナリファイルの両方に分割されたパッケージの場合、-loadフラグを回避すべきです。なぜなら
インデックスを計算する前にパッケージをロードすると、それが同じパッケージの一部を提供する他のファイルを遮断してしまうからです。
-loadを使わなければならないなら、最初にスクリプトを指定しなければなりません。そうでないとバイナリファイルからロードされたパッケージはスクリプトに定義されたパッケージを遮断する恐れがあります。
package
auto-load, index,
package, version
Copyright © 1996 Sun Microsystems, Inc.
Copyright © 1995-1997 Roger E. Critchlow Jr.
|