Tcl のインタラクティブ環境を保存する [Tcl]
Lisp 処理系とか統計処理言語の R とかではインタプリタでひとしきり関数や変数を定義した後で現在の環境を保存し、次回起動の時に同じ時点から再開できるような機能が付いている。これを Tcl で可能にするプロシージャを作ってみた。
proc save {filename} {
set f [open $filename w]
foreach var [info globals] {
if {![uplevel #0 array exists $var]} {
puts $f "set {$var} {[uplevel #0 set $var]}"
} else {
puts $f "array set {$var} {[uplevel #0 array get $var]}"
}
}
foreach fun [info procs] {
puts $f "proc $fun {[info args $fun]} {[info body $fun]}"
}
close $f
}
ここで使用しているポイントとなるコマンドは以下のとおり。
info globals: グローバル変数名の一覧を取得
info procs: プロシージャの一覧を取得
info args: プロシージャの仮引数を取得
info body: プロシージャのコード部分を取得
まず info globals で得た変数名を foreach にかけてそれぞれファイル保存を行う。配列の場合はそのままでは文字列形式にならないので変わりに array get を使ってシリアライズする必要がある。
ここで変数の内容を取得するのに単に set $var や array get $var としては上手くいかない。そうするとプロシージャのローカルのシンボルテーブルにしかアクセスできないからだ。コマンドをグローバル環境で評価するには uplevel #0 を使う。
プロシージャの保存の方は残りの info 系コマンドを使って素直に実装できる。特に説明を要する部分はないと思う。
対応する restore コマンドは作っていない。上記コードの保存形式は Tcl のスクリプトそのものなので source コマンドを使うことでリストアできる。(このやり方だと変数にバイナリが入っていると上手く行かないかもしれないのでそれに対応したい場合はちゃんと restore コマンドを作った方がよいだろう)
コメント 0