こんにちは、山本です。
"Kosuke Yamazaki <kyam@...>"さんは書きました:
> Tcl で以下のようにプロシージャ内でコメントアウトしたいのですが、
> コメント行内の「{」を認識してしまうようです。Tcl の仕様として
> コメント行にある「{」や「}」の数もカウントするのでしょうか。
>
> proc test {} {
> #{
> puts "aaa"
> }
Tcl8.4.1の実装を見てみましたが、open brace(「{」記号のこと)が出現すると
たとえその行の先頭が'<whitespace>#'となっていてもopen braceを数えるよう
になっています。
"藤岡和夫 <kazuf@...>"さんは書きました:
> プロシージャ内のコメント行では、{}をセットで使う必要があるということにな
> りますか。\{、\}とエスケープすればセットで使わなくてもエラーになりません
> 。{}を文法の構成要素として捉えていますね。コメントの性質を考えるとバグな
> んでしょう。
procコマンドやforeachコマンドなど「引数」にスクリプトを指定できるコマンド
だけについて注目していると、コメント行のopen braceが数えられるのはバグでは
ないかと感じます。
しかし、Tclという言語では、brace記号はあくまで「close braceが現れるまで一つ
の単語として括る」というものです。Tclにとってのbrace記号は、ブロックという
よりもむしろPerlのシングルクォーテーションや q// で文字列を括っているような
ものだと考えると解りやすくなると思います。
また、Tclでは、文字列中にbrace記号が現れると、その間に括られている文字列を
リストの一要素として扱うことができるため、backslashでquoteされていない
open braceとclose braceを一対一にしておかないと正常にスクリプトを動作させる
ことができなくなります。
例えば、setコマンドで説明すると:
set hoge "a b {c d} e" ;# ←OK: hogeに「a b {c d} e」という文字列が設定される
set foo {a b {c d} e} ;# ←OK: fooに「a b {c d} e」という文字列が設定される
set bar {a b {c d} e ;# ←NG: 最初のopen braceに対応するclose braceが無い
puts [lindex $foo 2] ;# 「c d」が表示される
これはよく見かけるsetコマンドの書き方ですが、次のように複数行に渡って
setコマンドを記述することもできます。procコマンドなどもこれと同じように
構文解析されます:
set foo {
a
b
# {
c
d
}
e
}
# ↑
# OK: fooに「\n a\n b\n # {\n c\n d\n }\n e\n」という文字列が設定される
puts [lindex $foo 3] ;# 「\n c\n d\n 」が表示される
set bar {
a
b
# {
c
d
}
e
# ↑
# NG: 最初のopen braceに対応するclose braceが無い
このように、brace記号の間にあるopen braceやclose braceには特別な意味があるため、
注意が必要です。
なお、以下のように#の直後にopen braceがある場合は、本当はこのopen braceを
勘定すべきではないと思います。事実、lindexコマンドでリストの要素を取り出して
みると次のように解釈されています:
#{ ← 「#{」という一つの単語として取り出される
# { ← まず「#」という単語があり、「{」から次の単語が開始する
つまり、whitespaceがあるかないかで微妙に解釈が違ってきます。
だから、今回の↓はやっぱりバグと言えるのです。
proc test {} {
#{
puts "aaa"
}
なんだかややこしいですね(^^;。
--
Koichi Yamamoto,
http://homepage3.nifty.com/yamakox/