Tcl 8.5 の {expand} [Tcl]
Tcl 8.5 で新たに {expand} という表記が導入された。これはコマンドの追加ではなく、Tcl のコマンド解釈の方法に対する変更である。
これはこのようにして使う。
% {expand}{puts hello} hello
何が起こっているかわかるだろうか。もうひとつ例を挙げる。
% set greeting {Hello World} Hello World % list $greeting {Hello World} % list {expand}$greeting Hello World
list コマンドは可変長の引数をとり、それをリスト化(空白で区切られた文字列)したものを返すコマンドだが、2つ目のコード例の最初の list コマンドでは変数 $greeting の中身が空白で区切られていようとも list コマンドに対して与えられた引数は1つなので「Hello World」という空白入りの要素が1つだけ含まれたリストを返す。空白を含むリスト要素は中括弧で括られる。
次の {expand} を使った例では、まず {expand} に続く内容がコマンドラインの要素として展開される。だからこのコマンドは以下と等価になる。
% list Hello World Hello World
最初のコード例に戻ろう。この puts hello は中括弧でグルーピングされているから本来ならコマンドライン上の1要素として解釈されるはずだ。
% {puts hello} invalid command name "puts hello"
コマンドラインの最初の要素はコマンドだから「puts hello」というコマンドがない限りは上記のエラーになる。[1]
ところがもし要素が {expand} という修飾子(と呼ぶのかなんと呼ぶのか)で始まっていたら続く中身がコマンドライン上に展開される。従って「{expand}{puts hello}」は以下のコマンドと等価になるというわけだ。
% puts hello hello
しかし何故こんなものが導入されたのだろうか。
今までは (1) list コマンドのように可変長の引数リストをとって何かをするコマンドがあり、(2) そのコマンドに与えたいリストが Tcl リストとして存在する場合、以下のように eval を使う必要があった。
% eval list $greeting Hello World
さもなくば先に見たようにリストが単一の引数としてコマンドに与えられてしまうからだ。上記の eval を使う方法の代替が「list {expand}$greeting」ということになる。
だがこの表記の導入がいいものかどうかは疑問が残る。文法の追加は Tcl の簡潔性を次第に損なっていくものだし、これは別に 8.4 までの仕様でできないことではなく、いわば syntactic sugar のようなものだ。
まあそれにしてもいまさら 8.5 の新機能を一つ一つ試しているというのも1~2年くらい遅れているということなので tcl-core とかにちゃんと subscribe したほうがいいのかもしれない。
[1] 余談だが Tcl では空白を含む名前のプロシージャを定義することもできる。
% proc {puts hello} {} { puts hello } % {puts hello} hello %
コメント 0