IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

ちょっとだけ tcl の勉強

tcl とは

スクリプト言語です

たまに tcl で書かれてるツールがあるので

tcl の文法を理解しておく

パッと見

tcl のシンボルのようなものは全部文字列。
tcl の行はリスト。
たとえば、以下の行は

package require hoge

LISP でいうと以下のようなデータになる

("package" "require" "hoge")

で、リストの先頭の文字列がコマンドとして実行されていく、コマンド以外のリストのようそはコマンドが数値として扱ったりする。

コマンド

リストの先頭の文字列のことをコマンドっていう。リストが評価されると、コマンドが実行される

print っぽいやつ

puts Hello!

全部文字列だから "Hello!" とかしなくていい。

コメント

puts Hello! # コメント

シャープで書く

空白をリストの区切りじゃなくて文字列の中に入れる

puts 'Hello world!'
puts "Hello world!"
puts {Hello world!}
puts { {Hello} {world!} } # "{Hello} {world!}" という文字列

中括弧かクオートで囲む
中括弧はネスト可能

変数

set hoge fuga

set コマンドが、リストの 2 個目の文字列を変数名として扱って、 3 個目の文字列を代入する。

puts $hoge   # fuga と表示される

$ を使って変数を展開する。
展開された変数はそこにクオートされて書かれていたのと同じ挙動をする

set hoge ts
pu$hoge "Hello" # Hello と表示される

リストを作る

list hoge fuga

scheme の list みたいな感じ

コマンド置換

puts [join [list Hello world] " "]

コマンドをやった結果を別ので使いたい場合は大括弧を使う
大括弧を全部評価してから、その一個上のリストが評価される。

リストを評価

eval [list puts "Hello world!"]

schemeeval みたいな感じ

エラーの補足

catch {
   # ここにコマンド
} fid # fid という変数にエラーメッセージが入る

puts $fid

この中括弧もあくまで文字列。 catch コマンドが引数で受け取った文字列を、行単位でリストにしてさらに実行しているだけ
つまり LISP っぽく書くと以下のようなデータ

("catch" "
  some-command
  some-command
" "fid")

("puts" ("get" "fid"))

プロシージャ

proc hoge { arg1 arg2 arg3 } {
  puts [join [list "Hello " $arg1] " "]
  puts [join [list "Hello " $arg2] " "]
  puts [join [list "Hello " $arg3] " "]
}

当然中括弧内は文字列にすぎないので

proc hoge "arg1 arg2 arg3" "...略..."

と書いても同じである。
プロシージャはコマンドと同じように扱える

hoge amachang yamachang kamachang

if とかも文字列文字列

if { cond } {
  commands
}

ふー

これで、コマンドリファレンスを見ながらならだいたいの tcl で書かれたツールは読めるようになった。

感想

このメタプログラミング感といい。
「データ = プログラム」なところといい
scheme とすごく似てると思った。