ぱたへね

はてなダイアリーはrustの色分けができないのでこっちに来た

Tcl のすごいところ その1

おそらく続きません。
お仕事でTclを使う機会が増えてきて、いくつかアプリケーションも書いているのですが、Tclには時々驚くような機能があります。その中の一つを紹介します。

呼び出し側のループを制御する

Tclでは、procというコマンドを使って、他の言語でいうところの関数を定義します。関数から値を返すときは、他の言語と同じように return に続いて戻したい値を記述します。return を省略した場合は、最後に実行したコマンドの戻り値が、関数の戻り値になります。ここまでは普通ですね。

Tclが他の言語と違うのは、return にオプションを渡すことができ、オプションによって「呼び出し元」の制御を行う事ができます。例えば、return に -code break の引数をつけると、関数から戻ると同時に呼び出し元のループも抜け出します。良く意味が分からないですね。

詳しくはこちらを見てください。
http://www.freesoftnet.co.jp/tclkits/doc/TclCmdRef/TclCmd/return_jp.htm

では、実際にやってみましょう。
mainで、ループを使いながらfunc1を10回、func2を10回呼び出しています。main の中には break、continue、return が無いのですが、呼び出された関数の戻り値にパラメータを設定されているので、break、continue、returnと同じ動作が行われます。

proc func1 { i } {
    if {$i == 2} {
	# 2はcontinueなので表示されない
	puts "* continue *"
	return -code continue
    }
    if {$i == 5} {
	# 5はbreakなのでループを終了する。
	puts "* break *"
	return -code break
    }
}

proc func2 { i } {
    if {$i == 3} {
	# 3ならば呼び出し元もリターンする
	puts "* return *"
	return -code return
    }
}

proc main { } {
    for {set i 0} {$i < 10} {incr i} {
	func1 $i
	puts "func1 $i"
    }

    for {set i 0} {$i < 10} {incr i} {
	func2 $i
	puts "func2 $i"
    }
    puts "func2 が -code return を返すので、ここは表示されない"
}
# main呼び出し
main

このTclスクリプトを実行してみましょう。

c:\home\tmp>tclsh loop.tcl
func1 0
func1 1
* continue *
func1 3
func1 4
* break *
func2 0
func2 1
func2 2
* return *

c:\home\tmp>

呼び出された関数が、breakやreturnを行うため、どちらのループも10回回らずに終了しています。
Tcl怖いですね。