Tcl (頭字語として発音すると、/ ˈtɪk ( ə ) l /、tickleのように、または頭字語として、/ ˌtiːˌsiːˈɛl /、 TCLのように発音される。[ 8 ]元々はTool Command Language の略)は、高水準の汎用的なインタプリタ型動的プログラミング言語です。非常にシンプルでありながら強力であることを目標に設計されました。[ 9 ] Tcl は、変数代入やプロシージャ定義などのプログラミング構造も含め、すべてをコマンドの型に当てはめます。[ 10 ] Tcl は、オブジェクト指向、命令型、関数型、手続き型など、複数のプログラミング パラダイムをサポートしています。
Tclは、迅速なプロトタイピング、スクリプトアプリケーション、GUI、テストのために、Cアプリケーション[ 11 ]に一般的に組み込まれています。 [ 12 ] Tclインタープリタは多くのオペレーティングシステムで利用可能であり、Tclコードをさまざまなシステムで実行できます。Tclは非常にコンパクトな言語であるため、組み込みシステムプラットフォームでは、完全な形式と、他のいくつかの小さなフットプリントのバージョンの両方で使用されています。[ 13 ]
TclとTk拡張機能の組み合わせはTcl/Tk(「ティックル・ティーク」または「ティックル・TK」と発音)と呼ばれ、Tclでネイティブにグラフィカルユーザーインターフェース(GUI)を構築できます。Tcl/Tkは、 Tkinterの形で標準のPythonインストールに含まれています。
Tcl プログラミング言語は、 1988 年春にジョン・オースターハウトがカリフォルニア大学バークレー校で働いていたときに作成されました。[ 14 ] [ 15 ]元々は「フラストレーションから生まれた」もので、著者によれば、プログラマーが電子設計自動化(EDA) ソフトウェア、特に当時ジョンが専門的に取り組んでいたVLSI設計ツールMagicを拡張するための独自の言語を考案していたことがきっかけでした。[11] [ 16 ]その後、Tcl は独自に受け入れられるようになりました。オースターハウトは、1997 年に Tcl/Tk でACM ソフトウェア システム賞を受賞しました。 [ 17 ]
その名前は元々「Tool Command Language」に由来するが、慣習的にTCLではなくTclと表記される。[ 18 ]
Tcl のカンファレンスやワークショップは、米国とヨーロッパの両方で開催されています。[ 29 ] FlightAware [ 30 ]を含むいくつかの企業は、製品の一部として Tcl を使用しています。

Tclの機能には以下が含まれます
uplevel。upvarSafe-Tcl は、Tcl スクリプトがホストマシンやアプリケーションに損害を与えないように機能が制限された Tcl のサブセットです。[ 33 ]ファイルシステムへのアクセスは制限され、任意のシステムコマンドの実行は禁止されています。信頼されていないスクリプト内のコードを実行する信頼されていないインタプリタを使用するデュアル インタプリタ モデルを採用しています。電子メールにアクティブなメッセージを含めるために、 Nathaniel BorensteinとMarshall Roseによって設計されました。application /safe-tclとmultipart/enabled-mailがサポートされている場合、Safe-Tcl を電子メールに含めることができます。Safe-Tcl の機能はその後、標準の Tcl/Tk リリースの一部として組み込まれました。[ 34 ] [ 35 ]
Tcl の構文と意味は、十二の規則[ 36 ]で規定されており、これは十二の規則として知られています。[ 37 ]
Tclスクリプトは、一連のコマンド呼び出しで構成されます。コマンド呼び出しは、空白で区切られ、改行またはセミコロンで終わる単語のリストです。最初の単語はコマンド名で、言語に組み込まれているもの、利用可能なライブラリにあるもの、またはスクリプト自体で定義されているものがあります。それに続く単語は、コマンドへの引数として機能します。
コマンド名 引数1 引数2 ... 引数N
次の例では、puts(「put string」の略)コマンドを使用して、ホストコンソールにテキスト文字列を表示します。
「こんにちは、世界!」と表示します。これは「Hello, World!」という文字列と、それに付加された改行文字を標準出力デバイスに送信します。
変数や他のコマンドの結果を文字列に代入することができます。例えば、次の例では、set コマンドとexprコマンドを使用して計算結果を変数に格納し(Tcl では代入=演算子として を使用しないことに注意してください)、その後puts コマンドを使用して結果を説明文とともに出力しています。
# expr はテキスト文字列を式として評価しますset sum [expr 1 + 2 + 3 + 4 + 5 ] puts "1~5 の数値の合計は $sum です。"この#文字はコメントを導入します。コメントは、インタープリタがコマンド名を期待する場所であればどこにでも記述できます。
# 中括弧を使用すると、変数の置換は expr によって実行されます。set x 1 set sum [expr { $x + 2 + 3 + 4 + 5 }]; # $x は expr にパラメータを渡す前に置換されません。# expr は式を評価する際に $x を 1 に置換します。 puts "1 から 5 までの数値の合計は $sum です。" ; # sum は 15 です# 中括弧がない場合、変数の置換は定義箇所で行われます (字句スコープ) set x 2 set op * set y 3 set res [expr $x$op$y ]; # $x、$op、および $y が置換され、式は 6 に評価されますputs "$x $op $y は $res です。" ; # $x、$op、$y、および $res が置換され、文字列として評価されますこれらの例からもわかるように、この言語にはコマンドという基本的な構成要素が一つだけ存在します。引用符の仕組みと置換規則によって、各コマンドへの引数がどのように処理されるかが決まります。
コマンドや引数の解析が行われる前に、特別な置換処理が1つ行われます。行末(改行の直前)の文字がバックスラッシュの場合、バックスラッシュと改行の組み合わせ(および改行の直後のスペースやタブ)は単一のスペースに置き換えられます。これにより、行継続の仕組みが実現され、ソースコード内の長い行を次の行に折り返すことで、読者の利便性が向上します。
通常の引数処理を続けると、二重引用符文字 ( ) で始まる単語は"次の二重引用符文字まで続きます。したがって、このような単語には空白文字やセミコロンを含めることができますが、これらの文字は特別な意味を持つものとして解釈されません (つまり、通常のテキスト文字として扱われます)。開き中括弧文字 ( {) で始まる単語は次の閉じ中括弧文字 ( }) まで続きます。中括弧内では、前述のバックスラッシュと改行の削除を除き、すべての置換が抑制されます。どちらの構造にも囲まれていない単語は、ベアワードと呼ばれます。
引用符なしの単語と二重引用符で囲まれた単語では、3種類の置換が発生する可能性があります。
[expr 1+2+3]その中に含まれる式の評価結果(この場合は 6)に置き換えられます。$fooは「foo」という名前の変数の内容に置き換えられます。変数名は、曖昧な場合(例: )に後続のテキストと区別するために、中括弧で囲むことができます${foo}ing。\nは改行に置き換えられます。置換処理は、各単語を一度スキャンして左から右へと進みます。置換されたテキストは、さらなる置換の可能性を探るために再度スキャンされることはありません。ただし、1つの単語内に複数の置換が含まれる可能性があります。
Tcl 8.5以降では、任意の単語に を接頭辞として付けることができ{*}、これにより、コマンド呼び出しを構築するために、単語が構成要素となるサブワードに分割されます(Lispの準引用機能,@のシーケンスに似ています)。
これらのルールにより、任意のコマンドの実行結果を他の任意のコマンドの引数として使用できます。ただし、Unixコマンドシェルとは異なり、Tclは明示的に指示されない限り文字列を再解析しないため、対話型の使用はやや煩雑になりますが、スクリプトによる使用はより予測可能になります(例えば、ファイル名にスペースが含まれていても問題は発生しません)。
単一の等号(=)は、言語において特別な役割を全く果たしません。二重等号( )は、コマンドや の最初の引数==など、式の中で等価性を判定するために使用されます。(どちらのコマンドも標準ライブラリの一部であり、ライブラリ内で特別な位置を占めているわけではなく、必要に応じて置き換えることができます。)exprif
Tcl コマンドの大部分、特に標準ライブラリのコマンドは可変引数であり、(スクリプト化されたコマンド手順のコンストラクタ) を使用すると、指定されていない引数のデフォルト値と、任意の数の引数を処理できるようにする包括的な引数を定義できます。proc
Tclは静的型付け言語ではありません。各変数には、整数、浮動小数点数、文字列、リスト、コマンド名、辞書、またはその他のあらゆる値を含めることができます。値は(構文上の制約に従って)必要に応じて他の型として再解釈されます。ただし、値は不変であり、値を変更するように見える操作は、実際には新しい値を返すだけです。
プログラムの実行とデータ操作に関する最も重要なコマンドは次のとおりです。
set変数に新しい値を書き込みます(変数が存在しない場合は作成します)。引数が1つのみの場合、指定された変数の値を返します(この場合、変数は存在している必要があります)。procは、一連のコマンドとして記述された指定された Tcl スクリプトを実行する新しいコマンドを定義します。 をreturn使用すると、呼び出し元にすぐに制御を戻すことができます。一般的な実行制御コマンドは以下のとおりです。
if条件(第1引数)が満たされた場合、指定されたスクリプト本体(第2引数)を実行します。その後に、elseif代替条件と本体、またはelse補完ブロックから始まる追加の引数を指定できます。while条件(最初の引数)が満たされている限り、指定されたスクリプト本体の実行を繰り返します。foreach指定された本体を実行し、制御変数にリスト要素が1つずつ割り当てられます。for制御変数、条件(例while:)および追加の「次の反復」ステートメント(本体の実行後に実行されるコマンド)を初期化するためのショートカットswitch条件付きコードの評価を簡素化します。引数を複数のケースと比較し、一致するケースに関連付けられたコードを実行します。文字列比較、正規表現、およびグロブスタイルの比較をサポートしています。上記のループコマンドは、以下のコマンドによってさらに制御できます。
break本体の実行を中断し、ループコマンドから戻ります。continue本体の実行を中断しますが、制御はループコマンドに戻ります。 の場合whileは再びループすることを意味し、forおよび の場合はforeach次の反復を開始します。returnプロシージャの境界に到達するまで、プロシージャのどの深さであっても、現在の本体の実行を中断し、指定された値を呼び出し元に返します。expr引数を別の式インタープリタに渡し、評価された値を返します。なお、同じインタープリタは、条件式ifやループコマンドにも使用されます。listこのコマンドは、すべての引数を含むリストを作成します。引数が指定されていない場合は、空の文字列を作成します。このlindexコマンドは、結果に対して使用することで、元の引数を再抽出できます。array配列変数を操作します。dict辞書を操作します(バージョン8.5以降)。辞書は偶数個の要素を持つリストであり、2つの要素ごとにキーと値のペアとして解釈されます。regexp正規表現を文字列と照合します。regsub正規表現パターンマッチングに基づいて置換を実行します。uplevelは、コマンドスクリプトをスタック上の現在の最も内側のスコープ以外のスコープで実行できるようにするコマンドです。upvar別のスタックフレーム内の変数へのリンクを作成します。namespaceコマンドと変数に対して、個別のコンテキストを作成、アクセス、および破棄できます。apply匿名関数を適用します(バージョン8.5以降)。coroutine、、yieldおよびコルーチンyieldtoから値を生成および生成します(バージョン8.6以降)。try、、trapまた、finallyエラーや例外を捕捉して処理することができます(バージョン8.6以降)。catchスクリプトを評価し、その評価結果の戻りコードを返します。zlibZlibライブラリの圧縮機能とチェックサム機能へのアクセスを提供します(バージョン8.6以降)。uplevelコマンドスクリプトをスタック上の現在の最内スコープ以外のスコープで実行できるようにする。コマンドスクリプト自体がアップレベルコマンドを使用するプロシージャを呼び出す可能性があるため、結果としてコールスタックがコールツリーに変換される。[ 38 ]
これは元々、Tclプロシージャが組み込みコマンド(for、if 、 whileなど)を再実装しつつ、ローカル変数を操作できるようにするために実装されました。例えば、次のTclスクリプトはforコマンドの再実装です(例外処理は省略)。
proc for { initCmd testExpr advanceCmd bodyScript } { uplevel 1 $initCmd set testCmd [ list expr $testExpr ] while {[uplevel 1 $testCmd ]} { uplevel 1 $bodyScript uplevel 1 $advanceCmd } }upvar現在のプロシージャ内の1 つ以上のローカル変数が、囲んでいるプロシージャ呼び出し内の変数またはグローバル変数を参照するように設定されます。upvar コマンドは、名前によるプロシージャ呼び出しの実装を簡素化し、Tcl プロシージャとして新しい制御構造を構築することを容易にします。[ 39 ]
組み込みincrコマンドと同様に動作するdecrコマンドですが、変数に値を加算するのではなく減算します。
proc decr { varName {デクリメント1 }} { upvar 1 $varName var incr var [expr { -$decrement }] }Tclでは再帰tailcallがサポートされており、コマンドによって簡略化されています。このコマンドは、次の呼び出しで現在のスタックフレームを再利用するため、スタックオーバーフローの問題を防止します。
これはコラッツ数列を計算する例です。
proc collatz { n } { puts $n if { $n > 1 } { if { $n % 2 == 0 } { tailcall collatz [expr { $n >> 1 }] } else { tailcall collatz [expr { $n * 3 + 1 }] } } }このtailcallコマンドは呼び出し元に限定されず、他の関数を呼び出すためにも使用できます。
Tcl 8.6では、2012年に組み込みの動的オブジェクトシステムであるTclOOが追加されました。[ 31 ]これには次のような機能が含まれています。
oo :: class create fruit { method eat {} { puts "yummy!" } } oo :: class create banana { superclass fruit constructor {} { my variable peeled set peeled 0 } method peel {} { my variable peeled set peeled 1 puts "skin now off" } method edible ? {} { my variable peeled return $peeled } method eat {} { if { ! [ my edible ? ]} { my peel } next } } set b [ banana new ] $b eat → prints "skin now off" and "yummy!" fruit destroy $b eat → error "unknown command"Tclには2012年までオブジェクト指向(OO)構文がなかったため[ 31 ] 、オブジェクト指向プログラミングを可能にするための様々な拡張パッケージが登場しました。これらは既存のTclソースコードに広く使用されています。よく使われる拡張機能には以下のようなものがあります。
TclOO は、強力なオブジェクト指向システムを構築するためだけでなく、拡張パッケージがそれを基盤としてオブジェクト指向の抽象化を構築できるようにするためにも追加されました。TclOO のリリース後、incr Tcl はTclOO を基盤として使用するように更新されました。[ 27 ]
Tcl Web Serverは、HTTPプロトコルサーバーを純粋なTclで実装したものです。標準のTclインタープリタ上でスクリプトとして動作します。
Apache Rivet は、 Apache HTTP Server用のオープンソースのプログラミング システムで、開発者は Tcl をスクリプト言語として使用して動的な Web アプリケーションを作成できます。Rivet はPHP、ASP、JSPに似ています。Rivet は主に Damon Courtney、David Welton、Massimo Manghi、Harald Oehlmann、 Karl Lehenbauerによって開発されました。Rivet は、データベースとのやり取り (Oracle、PostgreSQL、MySQL、SQLite など) や、 GD Graphics Libraryなどの人気アプリケーションへのインターフェースなど、無数の機能を提供する、公開されている何千もの Tcl パッケージを使用できます。
Tcl はC言語とネイティブにインターフェースします。[ 40 ]これは、Tcl が元々 C 言語で書かれたコマンドに構文的なフロントエンドを提供するフレームワークとして書かれたためであり、言語内のすべてのコマンド (キーワードである可能性のあるもの、例えばifや などwhile) はこのように実装されています。各コマンド実装関数には、コマンドの (既に置換された) 引数を記述する値の配列が渡され、関数はそれらの値を自由に解釈できます。
デジタルロジックシミュレータには、 Verilog、VHDL、SystemVerilogなどのハードウェア言語をシミュレートするためのTclスクリプトインターフェースが含まれていることが多い。
任意の C 関数と Tcl ランタイムを接続するために必要なコードを自動的に生成するツール ( SWIG、Ffidlなど) が存在し、 Critcl はその逆を行い、任意の C コードを Tcl スクリプト内に埋め込み、実行時にDLLにコンパイルすることを可能にします。
Tcl言語は、GUI、ターミナルベースのアプリケーション自動化、データベースアクセスなど、追加機能を提供する拡張パッケージを常にサポートしてきました。よく使用される拡張機能には、以下のようなものがあります。