補足:引数をブレスで挟むことのもうひとつの意味
出典: フリー百科事典『ウィキペディア(Wikipedia)』 (2021/08/10 13:51 UTC 版)
「Tcl/Tk」の記事における「補足:引数をブレスで挟むことのもうひとつの意味」の解説
Tcl パーサーから渡された引数がコマンド内部で評価されるか否かは重要である。ここでの評価とはコマンド置換や変数置換のことである。例えば算術演算を行う expr コマンドは引数を内部で評価する。従って以下の2つのコマンドは同じ結果を返す。 expr $a*$b expr {$a*$b} Tcl パーサーが行ってくれずとも、exprコマンドが内部で変数置換しているので同じ結果が得られるのである。ifコマンドやwhileコマンドは第1引数として与えられた文字列を、コマンド内部で expr によって評価し、その結果を使う。 set val true if $val {~処理~} while $val {~処理~} Tcl パーサは第一引数の「$val」を評価して「true」(文字列)に書き換える。同様に第二引数「{~処理~}」を評価して、文字列リテラルなのでそのまま同じ値「{~処理~}」に書き換え、以下のようにする。 if true {~処理~} while true {~処理~} Tcl パーサはその後、true と {~処理~} を if、while コマンドに渡し、if、while コマンド側は受け取った文字列を expr コマンドに「[expr true]」として渡し、その結果をもって処理を続ける。気をつけなければならないのは while コマンドは {~処理~} をひと通り評価し終えた後、再度、第一引数を expr で評価するが、上記のコードでは与えられている値が true なので {~処理~} の中に「set val false」のような文があったとしても、第一引数で与えられた値そのものは変化しないので、ループを無限に繰り返すことになる({~処理~} の中に break コマンドが含まれていない場合)。 set val true if {$val} {~処理~} while {$val} {~処理~} この場合、Tcl パーサは引数を順に評価し、第一引数として「{$val}」という4文字の文字列リテラルを、第二引数として「{~処理~}」を、if、while コマンドに渡す。if、while コマンド側は受け取った文字列を expr コマンドに「[expr {$val}]」として渡し、その結果をもって処理を続ける。while コマンドは {~処理~} をひと通り評価し終えた後、再度、第一引数を expr で評価するが、上記のコードでは与えられている値が {$val} なので {~処理~} の中で「set val false」のような文があれば、その評価値も false になって、その時点で繰り返し処理を終了する。 一方、switchコマンドの第1引数は内部では評価されない。したがって下記の2番目の記述は期待する結果が得られない。 switch $val {...} switch {$val} {...} もし引数をコマンド内部で評価してくれるならば、その引数はブレス({})で挟んで渡した方が効率が良い。Tclパーサーとコマンドの両方による多重評価処理を回避できるからである。このような理由により、ifコマンドやwhileコマンドやforコマンドの引数は常にブレスで挟むべきである。特にループの条件式は必ずブレスで挟む必要がある。ブレスで挟まないと変数置換されてからループコマンドに渡されてしまうので、定数を並べた条件式になってしまい、無限ループをもたらす。
※この「補足:引数をブレスで挟むことのもうひとつの意味」の解説は、「Tcl/Tk」の解説の一部です。
「補足:引数をブレスで挟むことのもうひとつの意味」を含む「Tcl/Tk」の記事については、「Tcl/Tk」の概要を参照ください。
- 補足:引数をブレスで挟むことのもうひとつの意味のページへのリンク