2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

TclAdvent Calendar 2018

Day 5

Tclのlambda式

Last updated at Posted at 2018-12-04

apply

Tclでlambda式を使う手段として、Tcl 8.6でapplyコマンドが標準装備されました。

実は私はlambda式のメリットを理解できていません。このため、普段はapplyコマンドを使うことがありません。

だけどもしかしたら知ってしまえば使わずにはいられないくらい便利なものかも知れない・・・とも思うわけで、勉強がてらapplyコマンドを試してみました。

基本的な使い方

applyコマンドのヘルプによれば書式は以下の通りです。

apply func ? arg1 arg2 ... ?

で、最も簡単な例だと

puts [apply {{a b} {expr $a + $b}} 1 2]

を評価すると「3」が表示される、と。

まぁ、機能は何となく分かります。しかし問題は「で?」という感想しか出せないところ。

ヘルプで紹介されている便利な使い方

ヘルプでは「traceのコールバックが書きやすいよ」と紹介されています。

applyのヘルプより
trace add variable vbl write {apply {{v1 v2 op} {
	upvar 1 $v1 v
	puts "updated variable to \"$v\""
}}}

逆にapplyを使わなかったらこうなるんでしょうね。

trace add variable vbl write report

proc report {v1 v2 op} {
	upvar 1 $v1 v
	puts "updated variable to \"$v\""
}

まぁ、確かにapplyを使うことでtraceからしか呼び出さないコールバック関数にわざわざ「report」なんてな名前を付けずに済みます。

しかし「そもそもtraceはデバッグ用の機能で他の変数の監視もするから関数化しとくべき」とか「ゴチャゴチャして可読性さがる」という印象の方が強い。

頑張って無理にでも使ってみた

TclでHello, world! ~その2~」に書いたTCPのEchoサーバーを無理やりapplyで書いてみました。

hello1.tcl
socket -server [list apply {{sock host port} {
    fconfigure $sock -buffering line -encoding utf-8 -translation crlf
    fileevent $sock readable [list apply {{sock} {
		set data [gets $sock]
		if {[eof $sock]} {
			close $sock
		} else {
			puts $sock $data
		}
	}} $sock]
}}] 9999
vwait forever

ちぇんと動作しました。が・・・う~ん、やっぱりゴチャゴチャして理解しにくい。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?