2018/11/30

シンプルで面白いTcl/Tk

Tcl/Tkとは

Tcl/Tkの名前は、プログラミングをやったことがある方ならば、一度は聞いたことがあると思います。私が初めてその名を聞いたのは、Pythonの勉強で標準ライブラリであるtkinterを使ってみようと思った時でした。
一般的にGUI作成ツールという印象が強いかもしれませんが、Tclは汎用スクリプト言語です。したがって、変数、リスト、条件分岐、ループ処理、関数などもあります。wishというものもあり、これを使うとウィンドウが表示され、対話的にGUIの作成の勉強になります。Tcl/Tkのインストール方法は各プラットフォームによってことなります。
インストールが完了しましたら、早速試してみましょう。

$ tclsh

% expr 2 + 3
5
% puts "Hello"
Hello
% # これはコメントです。
%
%は、Pythonでの>>> つまり、プライマリープロンプトです。exprputsは一見どちらも出力コマンドに見えますが、例えばexpr "Hello"とやると、エラーになります。exprは、引数として与えられた式を評価して、結果を文字列として出力します。文字列をそのまま出力したい場合は、puts(標準出力)を使うようです。しかし、以下のようにすると出力できます。

% expr {"Hello"}
Hello
{}は、Tcl/Tkではリストを表します。リスト内の要素は空白文字で区切ります。

% set x {1 2 3 4 5}
1 2 3 4 5
% puts $x
1 2 3 4 5
上記のコードでは新たに変数束縛を行いました。set 変数名 値という形で変数束縛を行うことができます。呼び出しは$変数名となります。
次は条件分岐やループ処理などになりますが、ここまでくるとtclファイルを作ったほうが、いろいろ試すことができるので、ファイルの使い方のみご紹介します。
拡張子は.tclにしてください。そして$tclsh hello.tclのような形で実行できます。また、シェバン(私の場合は#!/usr/bin/tclsh)を書いておいて、実行権限($chmod +x hello.tcl)を与えることで./hello.tclという形でも実行できます。

wish

wishは最初に書いたように、対話的にGUIの作成を体験できます。インストール時に同梱されているはずなので、すぐに使うことができます。実際やってみたほうがわかりやすいと思いますので、ここではスクリーンショットはなしで、簡単なコードのみ紹介させていただきます。

$ wish
% button .b -text "hello"
.b
% pack .b
僅かこの二行で、helloボタンが表示されます。
こちらもまた.tclファイルに保存して、シェバンを私の場合は#!/usr/bin/wishにして、$ wish hello.tclを実行すると、ウィンドウが表示されます。
あくまで私の個人的な感想ですが、少しCommon Lispに似たような雰囲気があります。そしてGUIと密接につながっているこのような言語は、私がまだ知らないだけだと思いますが、めずらしい存在に感じます。私もまだまだ勉強しなければ使いこなすことはできませんが、密かに魅力を感じている言語です。

追記

せっかくなので、簡単なプログラムをご紹介します。以下のプログラムはカラーコードを扱うものです。

#!/usr/bin/wish

label .l1 -bg #000 -width 100 -height 10
label .l2 -text "color"

scale .s1 -label R -orient h -from 0 -to 255 -variable red \
          -command change_color
scale .s2 -label G -orient h -from 0 -to 255 -variable green \
          -command change_color
scale .s3 -label B -orient h -from 0 -to 255 -variable blue \
          -command change_color
pack .l1 .l2 .s1 .s2 .s3 -fill both

proc change_color {n} {
    global red green blue
    set color [format "#%02x%02x%02x" $red $green $blue]
    .l1 configure -bg $color
    .l2 configure -text "$color"
}
Tclでは関数はprocで定義します。Nimと同じですね。ただし、Nimではversion0.19から新たにfuncというaliasも導入されました。これについては過去の記事に書いたような記憶があります。関数内部のglobalはPythonにもありますね。もしTcl/Tkが使える環境の場合、こちらのプログラムを試してみてください。