| Tcl | |
|---|---|
| パラダイム | マルチパラダイム:イベント駆動型、関数型、命令型、オブジェクト指向 |
| 設計 | ジョン・アスターハウト |
| 開発者 | TCLコアチーム[ 1 ] |
| 初登場 | 1988年 (1988年) |
| 安定版リリース | |
| 型付けの規律 | 動的型付け、すべてが文字列 |
| 実装言語 | C、Tcl |
| ライセンス | BSDスタイル[ 3 ] |
| ファイル名拡張子 | .tcl、.tbc [ 4 ] |
| ウェブサイト | www |
| 主要な実装 | |
| ActiveTclアンドロウィッシュ | |
| 方言 | |
| ジム、イーグル | |
| 影響を受けた | |
| AWK、Lisp | |
| 影響を受けた | |
| PHP、[ 5 ] PowerShell、[ 6 ] Tea、TH1 [ 7 ] | |
Tcl(発音は「ティクル」または「TCL」。[ 8 ]元々はTool Command Language)は、高水準、汎用、インタープリタ型の動的プログラミング言語です。非常にシンプルでありながら強力であることを目指して設計されました。[ 9 ] Tclは、変数の割り当てやプロシージャの定義といったプログラミング構造さえも、すべてをコマンドの型に当てはめます。[ 10 ] Tclは、オブジェクト指向、命令型、関数型、手続き型など、複数のプログラミングパラダイムをサポートしています。
TclはCアプリケーション[ 11 ]に組み込むことが一般的で、ラピッドプロトタイピング、スクリプトアプリケーション、GUI、テストなどに利用されています。 [ 12 ] Tclインタプリタは多くのオペレーティングシステムで利用可能であり、Tclコードを様々なシステムで実行できます。Tclは非常にコンパクトな言語であるため、組み込みシステムプラットフォームでは、完全な形式だけでなく、いくつかの小型バージョンも使用されています。[ 13 ]
Tcl とTk拡張機能の一般的な組み合わせはTcl/Tk (「tickle teak」または「tickle TK」と発音)と呼ばれ、Tcl でネイティブにグラフィカル ユーザー インターフェイス(GUI) を構築できます。Tcl/Tk は、標準のPythonインストールにTkinterの形で含まれています。
Tclプログラミング言語は、1988年春、ジョン・アウスターハウトがカリフォルニア大学バークレー校で働いていたときに作成されました。[ 14 ] [ 15 ]作者によると、もともとTclは「フラストレーションから生まれた」もので、[ 11 ]プログラマーが電子設計自動化(EDA)ソフトウェア、より具体的には当時ジョンが専門としていたVLSI設計ツールMagicを拡張するために独自の言語を考案したことがきっかけでした。 [ 16 ]その後、Tclは独自に受け入れられました。アウスターハウトは1997年にTcl/TkでACMソフトウェアシステム賞を受賞しました。 [ 17 ]
この名前は元々「Tool Command Language」に由来していますが、慣例的にはTCLではなくTclと表記されます。[ 18 ]
| 日付 | イベント |
|---|---|
| 1990年1月 | TCLがバークレー以外で発表(Winter USENIX)。 |
| 1990年6月 | 発表予定(Summer USENIX) |
| 1991年1月 | Tk (Winter USENIX) の最初の発表。 |
| 1993年6月 | 最初のTcl/Tkカンファレンス(バークレー)。[table]ジオメトリマネージャ([grid]の前身)、[incr Tcl]、TclDP、Groupkitが発表されました |
| 1997年8月 | Tcl 8.0ではバイトコードコンパイラと名前空間が導入されました。[ 19 ] |
| 1999年4月 | Tcl 8.1では、完全なUnicodeサポート[ 20 ]と高度な正規表現[ 21 ]が導入されました |
| 1999年8月 | Tcl 8.2でTcl拡張アーキテクチャ(TEA)が導入されました[ 22 ] |
| 2000年8月 | Tclコアチームが結成され、Tclはよりコミュニティ指向の開発モデルに移行しました。[ 1 ] |
| 2002年9月 | 第9回Tcl/Tkカンファレンス(バンクーバー)。StarKitパッケージングシステムの発表。Tcl 8.4.0リリース。[ 23 ] |
| 2007年12月 | Tcl 8.5では、新しいデータ型、新しい拡張リポジトリ、bignums [ 24 ] 、lambdas [ 25 ]、[ 26 ]が追加されました |
| 2012年12月 | Tcl 8.6では組み込みの動的オブジェクトシステム、TclOO、およびスタックレス評価が追加されました。[ 27 ] |
| 2024年9月 | Tcl 9.0では、64ビット機能、Unicodeコードポイントの全範囲のサポート、epollとkqueueの使用が追加されました[ 28 ] |
Tclカンファレンスとワークショップは米国とヨーロッパの両方で開催されています。[ 29 ] FlightAware [ 30 ]を含むいくつかの企業は、Tclを製品の一部として使用しています。

Tclの機能には以下が含まれます
uplevel。upvarSafe-TclはTclのサブセットであり、Tclスクリプトがホストマシンやアプリケーションに害を及ぼすことがないように機能が制限されています。[ 33 ]ファイルシステムへのアクセスは制限されており、任意のシステムコマンドの実行は防止されています。信頼できないインタープリタが信頼できないスクリプト内のコードを実行する、デュアルインタープリタモデルを使用しています。これは、Nathaniel BorensteinとMarshall Roseによって、アクティブなメッセージを電子メールに含めるために設計されました。Safe-Tclは、application/safe-tclとmultipart/enabled-mailがサポートされている場合、電子メールに含めることができます。Safe-Tclの機能は、その後、標準のTcl/Tkリリースの一部として組み込まれました。[ 34 ] [ 35 ]
Tclの構文と意味論は、Dodekalogueとして知られる12のルール[ 36 ]によってカバーされています。 [ 37 ]
Tclスクリプトは、一連のコマンド呼び出しから構成されます。コマンド呼び出しは、空白で区切られ、改行またはセミコロンで終了する単語のリストです。最初の単語はコマンド名で、言語に組み込まれている場合、利用可能なライブラリにある場合、またはスクリプト自体で定義されている場合があります。後続の単語はコマンドの引数として機能します。
コマンド名 引数1 引数2 ... 引数N
次の例では、puts (「put string」の略) コマンドを使用して、ホスト コンソールにテキスト文字列を表示します。
「Hello, World!」と入力しますこれにより、文字列「Hello, World!」が改行文字とともに 標準出力デバイスに送信されます。
変数や他のコマンドの結果を文字列に置き換えることができます。次の例では、set コマンドとexprコマンドを使用して計算の結果を変数に格納し (Tcl は=代入演算子として使用しないことに注意してください)、次にputs を使用して結果を説明テキストとともに出力します。
# expr はテキスト文字列を式として評価します。set sum [ expr 1 + 2 + 3 + 4 + 5 ]は「数値 1 から 5 までの合計は $sum です。」と入力します。文字はコメント#を表します。コメントはインタープリタがコマンド名を期待する場所であればどこにでも記述できます。
# 中括弧付きで、変数の置換は expr set x 1 set sum [expr { $x + 2 + 3 + 4 + 5 }] によって実行されます。# パラメータを expr に渡す前に $x は置換されません。# expr は式を評価する際に $x に 1 を代入します。puts " 1..5 の数値の合計は $sum です。" ; # 合計は 15 です。# 中括弧がない場合、定義箇所で変数の置換が行われます(レキシカルスコープ)set x 2 set op * set y 3 set res [expr $x$op$y ]; # $x、$op、$yが置換され、式は次のように評価されます 6 puts "$x $op $y is $res." ; # $x、$op、$y、$resが置換され、文字列として評価されますこれらの例からわかるように、この言語にはコマンドという基本的な構成要素が1つあります。引用符のメカニズムと置換規則によって、各コマンドの引数がどのように処理されるかが決まります。
コマンドや引数を解析する前に、特別な置換が行われます。行末の文字(つまり改行の直前)がバックスラッシュの場合、バックスラッシュと改行の組み合わせ(および改行直後のスペースやタブ)は1つのスペースに置き換えられます。これにより、ソースコード内の長い行を次の行に折り返して読みやすくすることができます。
通常の引数処理を続けると、二重引用符( )で始まる単語は"次の二重引用符まで拡張されます。したがって、このような単語には空白文字やセミコロンを含めることができますが、これらの文字は特別な意味を持つものとして解釈されません(つまり、通常のテキスト文字として扱われます)。開き中括弧({)で始まる単語は、次の閉じ中括弧(})まで拡張されます。中括弧内では、前述のバックスラッシュと改行の除去を除き、すべての置換形式は抑制されます。どちらの構造にも囲まれていない単語は、裸の単語と呼ばれます。
裸の単語と二重引用符で囲まれた単語では、次の 3 種類の置換が発生する可能性があります。
[expr 1+2+3]含まれる式(この場合は6)の評価結果に置き換えられます。$fooは「foo」という変数の内容に置き換えられます。変数名を中括弧で囲むことで、後続のテキストと区別することができます(例:${foo}ing)。\nは改行文字に置き換えられます。置換は、各単語を一回スキャンして左から右へと行われます。置換されたテキストは、さらなる置換の可能性を調べるために再度スキャンされることはありません。ただし、1つの単語には任意の数の置換が出現する可能性があります。
Tcl 8.5 以降では、任意の単語の前に を付けることが可能になりました{*}。これにより、コマンド呼び出しを構築する目的で、単語が構成サブワードに分割されます ( Lispの quasiquote 機能 ,@のシーケンスに似ています)。
これらの規則の結果として、任意のコマンドの結果を他の任意のコマンドの引数として使用できます。Unixコマンドシェルとは異なり、Tclは明示的に指示されない限り文字列を再解析しません。そのため、対話型の使用は煩雑になりますが、スクリプトでの使用はより予測可能になります(例えば、ファイル名にスペースが含まれていても問題はありません)。
単一の等号 ( =) は、言語において特別な役割を全く持ちません。二重の等号 ( ) は、コマンドや の最初の引数==などの式のコンテキストで等価性を判断するために使用されます。(どちらのコマンドも標準ライブラリの一部であり、ライブラリ内で特別な位置を占めるわけではなく、必要に応じて置き換えることができます。) exprif
Tcl コマンドの大部分、特に標準ライブラリは可変長引数であり、proc(スクリプト コマンド プロシージャのコンストラクター) を使用すると、指定されていない引数の既定値とキャッチオール引数を定義して、コードで任意の数の引数を処理できるようになります。
Tclは静的型付けではありません。各変数には、整数、浮動小数点数、文字列、リスト、コマンド名、辞書、その他あらゆる値を格納することができます。値は必要に応じて(構文上の制約に従って)他の型に再解釈されます。ただし、値は不変であり、値を変更するように見える操作は、実際には新しい値を返すだけです。
プログラムの実行とデータ操作に関する最も重要なコマンドは次のとおりです
set変数に新しい値を書き込みます(存在しない場合は変数を作成します)。引数を1つだけ指定した場合は、指定された変数の値を返します(この場合、その変数は存在している必要があります)。proc新しいコマンドを定義します。このコマンドを実行すると、コマンドのセットとして記述された特定の Tcl スクリプトが実行されます。これをreturn使用して、呼び出し元に制御をすぐに返すことができます。通常の実行制御コマンドは次のとおりです。
if条件(第一引数)が満たされた場合、指定されたスクリプト本体(第二引数)を実行します。その後に、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エラーと例外をトラップして処理できます (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 コンストラクター{} { 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を基盤としてオブジェクト指向抽象化を構築できるようにするためにも追加されました。TclOOのリリース後、incr TclはTclOOを基盤として利用するように更新されました。[ 27 ]
Tclウェブサーバーは、HTTPプロトコルサーバーの純粋なTcl実装です。標準のTclインタープリタ上でスクリプトとして実行されます
Apache Rivetは、 Apache HTTP Server用のオープンソースプログラミングシステムであり、開発者が動的なWebアプリケーションを作成するためのスクリプト言語としてTclを使用することができます。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言語で書かれたコマンドの構文的なフロントエンドを提供するためのフレームワークとして書かれたためであり、C言語のすべてのコマンド(またはなど、キーワードとなる可能性のあるものも含む)はこのように実装されています。各コマンド実装関数には、コマンドの(既に置換された)引数を表す値の配列が渡され、関数はそれらの値を必要に応じて自由に解釈します。 ifwhile
デジタルロジック シミュレータには、多くの場合、 Verilog、VHDL、 SystemVerilogハードウェア言語をシミュレートするための Tcl スクリプト インターフェイスが含まれています。
任意の C 関数と Tcl ランタイムを接続するために必要なコードを自動的に生成するツール (例: SWIG、Ffidl ) が存在し、 Critcl はその逆を行い、任意の C コードを Tcl スクリプト内に埋め込み、実行時にDLLにコンパイルできるようにします。
Tcl言語では、GUI、ターミナルベースのアプリケーション自動化、データベースアクセスなどの追加機能を提供する拡張パッケージが常にサポートされています。一般的に使用される拡張機能には、以下のものがあります