Tcl/Tkとは
Tcl(ティクル)は、そのシンプルな文法が特徴の
スクリプト言語です。コマンド行のみで構造化された文法に従い、非常に小さなルールで広範囲の処理を記述できます。特に強力なGUIツールキットであるTkと組み合わせて「Tcl/Tk」として知られ、GUIアプリケーションを迅速に開発できる強力なスクリプティング環境を構築できます。
Tkは
クロスプラットフォームなGUI環境としても有名で、Tclだけでなく、
Perl、
Python、
Rubyなど他の言語からも利用可能です。
Tcl/Tkは、
UNIX、Windows、Macintoshといった主要な
オペレーティングシステム上で動作し、ウェブブラウザ上で動作するプラグイン「Tclet(ティクレット)」も存在します。
Tclの誕生
Tclは1988年に
カリフォルニア大学バークレー校のジョン・ケネス・オースターハウト博士によって開発されました。当時、アプリケーションに組み込むための標準的な
スクリプト言語がなく、各アプリケーションが独自の言語を実装していたため、利用者はツールごとに異なる
スクリプト言語を習得する必要がありました。
この非効率性を解消するため、オースターハウト博士は
UNIXアプリケーションにおける標準的な拡張
スクリプト言語を設計しました。これがTclの始まりであり、アプリケーションへの組み込みを容易にすることに重点が置かれました。具体的には、処理系をライブラリとして提供して
C言語で書かれたアプリケーションに容易に組み込めるようにし、言語構造を簡素化しつつ高い拡張性を持たせ、インタプリタ言語として実装されました。
Tkの登場
Tkは、Tcl用に開発されたGUIツールキットで、簡単なコードでGUIを作成できます。1990年代初頭にTclにバンドルされる形で公開され、
AppleのHyperCardに触発されて開発されました。当初はTclの活用事例の一つとして紹介されましたが、その使いやすさからTcl言語と共に人気を博しました。
Tclは、当初の設計意図とは異なり、アプリケーションの組み込み言語としてよりも、Tkと合わせた「Tcl/Tk」の形でGUIスクリプティング環境として広く利用されるようになりました。Tkの人気は特に高く、
Perl(
Perl/Tk)、
Python(Tkinter)、
Ruby(
Ruby/Tk)など、他の言語でも標準的なGUIキットとして利用されました。
Tcl/Tkの発展
1994年から1998年まで、オースターハウトが
サン・マイクロシステムズに在籍していた期間に、Tcl/Tkは同社で開発が進められました。この時期、サンはWWWクライアント環境の制覇を目指しており、Tcl/Tkもその流れに乗ってウェブに領域を拡大しました。ウェブブラウザ上でTk GUIを動作させるプラグイン「Tclet」や、ブラウザの
スクリプト言語としてのTclの組み込み、国際化対応(内部処理のUNICODE化)、インタプリタからバイトコンパイラへの変更による実行速度の向上など、Tcl/Tkはこの時期に機能的な大きな進歩を遂げました。
しかし、他技術との競合やブラウザでのサポート不足などにより、WWWを「第二のTk」として人気を拡大することはできませんでした。オースターハウトの退職後、Tcl/Tkの開発はオープンソースに移行し、現在も精力的に開発が続けられています。
現在の状況
2005年現在、Tcl言語は「Tcl/Tk」の知名度とは裏腹に、
Perl、
Python、
Rubyに比べて利用者数は少ないのが現状です。特に日本国内での利用者は限られています。しかし、EDAツールにおいては標準的な
スクリプト言語として広く利用されているほか、電子国土Webシステムでも一部でTcl言語が使用されています。
一方、Tkは、後発のGTK+や
Qtと並び、軽量
プログラミング言語における事実上の標準GUIツールキットの一つとして広く利用されています。
Tcl言語の特徴
Tcl言語の最大の特徴は「全てが文字列」として扱われる点です。Tclは、コマンド行の順次実行というシンプルな文法と、首尾一貫したリスト構造を組み合わせることで、非常に小さいルールで広範囲の処理をカバーします。
コマンド行はリストとして扱われ、先頭の要素がコマンド、それ以降の要素がコマンドへの引数となります。LISP言語に似た一貫性を持ちますが、リストの要素を区切る記号がブランクやタブであるため、他の言語に慣れた人には違和感があるかもしれません。
リスト構造
リストは文字列で構成され、要素はブランクまたはタブで区切られます。要素にブランクやタブを含めたい場合は、その要素をブレース({、})で囲む必要があります。
リストの抽出
Tclパーサーは、ソースコードからコマンド行としてリストを取り出す際、改行コードまたはセミコロン(;)をリストの終端と判断します。ただし、改行コードやセミコロンがブレースで囲まれている場合は、リストの終端とはみなしません。
ブラケット記号(コマンド置換)
Tclパーサーは、リストの先頭要素をコマンド名として認識します。引数要素がブラケット([、])で囲まれている場合、その中身をコマンド行として実行し、結果を本来の引数値として扱います。これがコマンド置換です。
$記号(変数置換)
Tclパーサーは、変数機能を介してコマンド間でのデータの受け渡しを可能にします。変数は`set`コマンドで生成され、$記号が先頭に付いた要素を変数名とみなし、その値で要素全体を置換します。これが変数置換です。
ダブルクォーテーション記号
ブレース({、})は、改行コードなどの特殊文字の機能を無効化しますが、コマンド置換子や変数置換子も同様に無効化します。コマンド置換と変数置換を有効にしつつ、空白を含む文字列を引数として渡すには、ダブルクォーテーション(")で囲む必要があります。
セミコロン記号(マルチコマンド)
複数のコマンドを1行に記述する場合は、コマンド行をセミコロン(;)で区切ります。
#記号(注釈行)
コマンドの位置に#を記述すると、その行末までがコメントとみなされます。
バックスラッシュ記号
1つのコマンドを複数行に記述する場合は、行末にバックスラッシュを付けます。また、$文字の前にバックスラッシュを置くと、$置換子の機能を抑制し、単なる文字として扱えます。
引数をブレースで囲む意味
Tclパーサーから渡された引数が、コマンド内部で評価されるか否かは重要です。評価とは、コマンド置換や変数置換のことです。例えば、算術演算を行う`expr`コマンドは引数を内部で評価します。`if`コマンドや`while`コマンドは、第1引数として与えられた文字列を、内部で`expr`によって評価し、その結果を使用します。
引数をブレースで囲むことで、Tclパーサーとコマンドの両方による多重評価を回避できます。特に、ループの条件式は必ずブレースで囲む必要があります。
コマンドの拡張
Tclには、ビルトインコマンドの他に、ユーザーが作成した拡張コマンドがあります。拡張コマンドは
C言語などで「コマンド本体関数」と「登録用関数」を記述し、ダイナミックリンクライブラリに格納して、組み込みコマンドの`load`を用いて登録します。
内部構造(Tclオブジェクト)
Tclパーサーは、スクリプト文字列を受け取り、処理結果を文字列で返しますが、内部では可能な限りバイナリ値を維持しています。変数やリストはTclオブジェクトとして存在し、文字列への変換が要求されない限り、数値は数値のまま、リストはリストのまま維持されます。
Tclオブジェクトは参照カウンタを持ち、参照が不要になった時点で自動的に削除されます。これにより、メモリ管理を容易にしています。スクリプト自体もTclオブジェクトとして存在します。
まとめ
Tclは、そのシンプルな文法と強力なGUIツールキットTkの組み合わせにより、幅広い分野で利用されています。組み込み用途からGUI開発まで、柔軟に対応できる点が魅力です。そのユニークな設計思想は、他の
スクリプト言語とは異なる視点を提供します。