|
パッケージとは? ここではTclスクリプトをパッケージにする方法を紹介しています。 C言語で拡張したライブラリをパッケージにする方法は こちらのページです。 便利なTclプロシージャができると、 それらを使うスクリプトを作るたびにコピー&ペーストで書くのではなく、 個別のスクリプトファイルにしておき source コマンドで読みこむほうが管理も楽です。 たとえば、"1999/09/01 12:00:00" のような日時表記から例の clock secondsが返すような形式の整数の日時表記に変換する timelocal というプロシージャを作ったとします。
#
# timelocal.tcl
#
proc timelocal {ymddate {time 0:0:0}} {
if {[regexp {([0-9]+)/([0-9]+)/([0-9]+)} \
$ymddate all year mon day]} {
return [clock scan "$mon/$day/$year $time"]
} else {
error "illegal date format: $ymddate"
}
}
proc isnewer {filename than} {
if {[file mtime $filename] > [timelocal $than 0:0:0]} {
return 1
} else {
return 0
}
}
ついでにあるファイルが年/月/日表記の指定した日付より新しいかどうかを調べるプロシージャ
isnewer もおまけでつけてやりました。
これを上のように独立したファイルtimelocal.tcl としておき、
どこか自分の好きなところにおいておきましょう。たとえば
/usr/watasi/tcl/lib にしたとすると、
# # app.tcl # source /usr/watasi/tcl/lib/timelocal.tcl # ...このように冒頭部に1行書くだけで timelocal プロシージャが使えるようになります。 …というのが伝統的なプロシージャの管理方法だったのですが、 これには大きな問題点があります。もし、事情でtimelocal.tcl の置き場所を変えてしまったとすると、それをsourceコマンドで呼び出している Tclスクリプトを1つずつ全部書き換えないといけません。 これに対し古いTcl/Tkではインデックスファイルを自動的に作る機能があったり、 また置き場所を各スクリプトにべた書きするのではなく環境変数などにしておく、 などの対策もありましたが、 より統一的なプロシージャファイル(Perlでいうモジュール) の管理機構として Tcl/Tk 8.0 で パッケージという機構が整備されました。 パッケージを使うと、
パッケージの作り方 ●パッケージを宣言する パッケージを作る手順ですが、まずプロシージャファイル内に package provideコマンドでこのファイルがパッケージになることを宣言します。
#
# timelocal.tcl
#
proc timelocal {ymddate {time 0:0:0}} {
if {[regexp {([0-9]+)/([0-9]+)/([0-9]+)} \
$ymddate all year mon day]} {
return [clock scan "$mon/$day/$year $time"]
} else {
error "illegal date format: $ymddate"
}
}
proc isnewer {filename than} {
if {[file mtime $filename] > [timelocal $than 0:0:0]} {
return 1
} else {
return 0
}
}
package provide timelocal 0.10
package provideの最初の引数は「パッケージ名」で、
普通英小文字からなる単語を使います。2つめは「バージョン番号」で、
新しくするたびに数字を増やすという約束さえ守れば、
どんなつけかたでも構いません。
●決めたディレクトリに「インストール」する
●pkgIndex.tcl を作る shell% tclsh % cd /progra~1/tcl/lib/mypkg % pkg_mkIndex . % exit shell%実際にできたpkgIndex.tclはこんな内容です。 # (コメントが入る) package ifneeded timelocal 0.10 [list source [file join $dir timelocal.tcl]]このファイルには、 なんという名前のパッケージが呼び出されたらどのファイルを読めばよいか、 またそのパッケージにはどんな名前のプロシージャが含まれているか、 という情報が書かれています。 複数のプロシージャファイルが同一ディレクトリにある場合に上の作業をすると、 ファイルそれぞれについて上のような package ifneededコマンド行が pkgIndex.tclに書き出されます。 もちろん、 上の内容のファイルを自分でテキストエディタで書いても一向に構いません。 Tcl/Tk処理系が起動すると、 上に書いたTcl標準のライブラリの下にあるディレクトリ内にあるパッケージは、 自動的に検索されます。 (階層的に検索されるので、 そのまたサブディレクトリ、そのまたサブディレクトリ…でもOKです) しかし、それ以外の場所、たとえば /home/watasi/lib/mypkg などに置いてしまうと、処理系はパッケージがそこにある、 ということ自体がわからないのでパッケージがロードできません。 その場合には、WindowsでもUNIXでも環境変数TCLLIBPATH にそのディレクトリをセットしておけばOKです。 set TCLLIBPATH=C:/home/watasi/lib/mypkgWindowsでもパスは/区切りにしておきます。また、複数のディレクトリを TCLLIBPATHで指定する場合には、 set TCLLIBPATH=C:/home/watasi/lib/mypkg C:/usr/common/libこのように空白で区切ります。 set TCLLIBPATH="C:/home/watasi/lib/mypkg C:/usr/common/lib"ではダメなので注意が必要です。
●パッケージを使う # # app.tcl # package require timelocal # ...パッケージを使うときには、timelocalとisnewer というプロシージャがtimelocalというパッケージに入っていることだけ知っていれば十分です。 上のようにpackage requireコマンドで自分はこのパッケージに含まれているプロシージャを使うよんと宣言します。 すると、このときには Tcl/Tk処理系がそのパッケージを探し、見つかればバージョン番号を返し、 見つからなければエラーを起こします。 そして最初にtimelocalかisnewerを使って処理をしようとした段階で、 実際に timelocal.tcl が自動的に source され、 その中のコードが実行されることになります。
●パッケージ機構のしくみ
|