Tcl 程式設計/函式
命令基本上分為 C 定義的命令、過程和別名(以及從 Tcl 8.5 開始的組合)。您可以使用
rename oldname newname
要刪除命令(使其不再可訪問),請使用空字串作為新名稱
rename oldname {}
內省:使用
info commands
這些命令在 C 中實現,並註冊為在 Tcl 直譯器中可用。它們可以來自 Tcl 核心,也可以來自已載入的共享庫(DLL)- 例如 Tk。
要獲取內建命令的列表,請從 info commands 的結果中減去 info procs 的結果
set builtins {}
set procs [info procs]
foreach cmd [info commands] {
if {[lsearch -exact $procs $cmd] == -1} {lappend builtins $cmd}
}
以下 C 定義的命令在新的 tclsh 中可用。有關詳細文件,請參閱相應的聯機幫助頁,例如,在 http://www.tcl.tk/man/tcl8.5/TclCmd/ - 我將只對每個命令進行簡要描述
- after
- 用於定時事件的命令組
- after msec ?script?
- 等待或在一段時間後執行指令碼
- append varName arg..
- 將引數追加到字串變數
- array
- 用於陣列的命令組
- binary
- 用於二進位制掃描和格式化的命令組
- break
- 終止當前迴圈
- case
- 已棄用,使用 switch
- catch script ?varName?
- 捕獲 script 中的可能的錯誤
- cd path
- 更改工作目錄
- clock
- 處理日期和時間的命令組
- close handle
- 關閉通道(檔案、套接字等)
- concat list..
- 將引數合併成一個空格分隔的列表
- continue
- 開始當前迴圈的下一個迭代
- encoding
- 處理字元集編碼的命令組
- eof handle
- 如果通道位於檔案末尾,則為 1,否則為 0
- error message ?info? ?code?
- 使用給定訊息引發錯誤
- eval arg..
- 將引數作為指令碼進行評估
- exec file arg..
- 執行一個獨立的程序
- exit ?int?
- 終止此程序,返回狀態 0..127
- expr arg..
- 算術和邏輯引擎,使用類似於 C 的語法和函式(變數引用使用 $name)。此外,從 Tcl 8.4 開始,有 eq 和 ne 運算子用於字串相等或不相等;從 8.5 開始,還有 in 和 ni 運算子用於列表包含或不包含
expr {"foo" in {foo bar grill}} == 1
expr 的引數在大多數情況下應該是 {花括號括起來的}。這可以防止 Tcl 解析器預先替換變數,而 expr 本身必須從字串中解析值。在花括號括起來的表示式中,expr 可以自行解析變數引用,並在可能的情況下直接獲取其數值。通常更快。唯一的例外是,當您想要從變數中替換運算子時,不應使用花括號
foreach op {+ - * /} {puts [expr 1 $op 2]}
- fblocked handle
- 如果上次輸入操作用盡了所有可用輸入,則返回 1,否則返回 0
- fconfigure handle -option value...
- 配置通道,例如其編碼或換行符轉換
- fcopy handle1 handle2
- 將資料從 handle1 複製到 handle2
- file
- 處理檔案的命令組
- fileevent
- 處理通道(可讀、可寫)事件(但不是檔案)的命令組
- flush handle
- 確保通道的緩衝區已寫入。在 puts -nonewline 之後很有用
- for initbody condition stepbody body
- 迴圈,與 C 的 for 有些類似
- foreach varlist list ?varlist list...? body
- 遍歷一個或多個列表。varlist 可以是單個或多個 varName。例如
% foreach {x y} {1 0 1 2 0 2 0 0} {puts "x:$x, y:$y"}
x:1, y:0
x:1, y:2
x:0, y:2
x:0, y:0
- format fstring arg..
- 將引數 %-格式化為 fstring,類似於 C 的 sprintf()
- gets handle ?varName?
- 從 handle 讀取一行。如果給出變數,則將行分配給它並返回讀取的字元數;否則返回行。保證防範緩衝區溢位
- glob ?-options? pattern..
- 匹配 glob 模式(可以包含 * 和 ? 萬用字元)的檔案列表
- global varName..
- 宣告給定的變數為全域性變數
- history
- 列出最近的互動式命令
- if condition ?then? body1 ?elseif condition body2...? ??else? bodyN?
- 條件語句
- incr varName ?amount?
- 將整數變數增加給定的數量(預設為 1)。使用負數來減少
- info
- 用於內省的命令組
- interp
- 用於直譯器的命令組
- join list ?separator?
- 將列表轉換為字串,在元素之間使用分隔符(預設為 " ")
- lappend varName arg..
- 將引數追加到列表變數。也可以用於確保變數存在
lappend x ;# corresponds to: if {![info exists x]} {set x ""}
- lindex list int..
- 透過整數索引(es)檢索列表中的元素
- linsert list int arg..
- 在列表的 int 位置插入引數
- list ?arg..?
- 從引數建立列表
- llength list
- 列表的長度
- load filename ?name?
- 載入共享庫(DLL)
- lrange list from to
- 返回整數索引 from-to 處的子列表
- lreplace list from to arg..
- 用引數替換列表中的子列表
- lsearch ?-options? list element
- 在列表中搜索元素,返回其整數索引,如果未找到,則返回 -1。可用於從列表中選擇元素子集(使用 -all 選項)
- lset varName int.. value
- 將命名列表變數中的現有元素設定為給定值,該元素由整數(es)索引
- lsort ?-options? list
- 對列表進行排序
- namespace
- 處理名稱空間的命令組
- open name ?mode ?permissions??
- 開啟檔案或管道,返回控制代碼
- package
- 處理包的命令組
- pid ?handle?
- 返回當前程序的 ID。也可以返回給定管道通道的管道的 pid 列表
- proc name arglist body
- 定義過程
- puts ?-nonewline? ?channel? string
- 將一行輸出到給定的通道(預設情況下為 stdout)。要防止從已關閉的管道(如 more 或 head)中出現錯誤,請使用
proc puts! str {if [catch {puts $str}] exit}
- pwd
- 返回當前工作目錄
- read handle ?int?
- 從 handle 讀取 int 個位元組(如果沒有給出 int,則讀取所有位元組)
- regexp ?-options? re string ?varName...?
- 在字串中匹配 re 的正則表示式,可能將帶括號的子匹配分配給給定的變數
- regsub ?-options? re value substring ?varName?
- 用子字串替換 value 中正則表示式 re 的出現次數。如果給出 varName,則將新值分配給它,並返回替換次數;否則返回新值
- rename cmdName1 cmdName2
- 將命令從 cmdName1 重新命名為 cmdName2,如果 cmdName2 為 {},則刪除 cmdName1
- return ?value?
- 退出當前過程或已原始碼化的指令碼
- scan string format ?varName...?
- 根據字串中的 %-格式提取值到給定的變數。類似於 C 的 sscanf()
- seek channelId offset ?origin?
- 將檔案中的指標移動到給定位置
- set varName ?value?
- 如果給出,則將變數設定為值,並返回變數的值
- socket ?-myaddr addr? ?-myport myport? ?-async? host port
- 開啟 TCP 連線的客戶端作為通道
- socket -server command ?-myaddr addr? port
- 開啟 TCP 連線的伺服器端,為客戶端請求註冊一個處理程式回撥命令
- source filename
- 評估給定檔案的內容
- split list ?charset?
- 將字串拆分為列表,使用 charset 字串中的任何字元作為分隔符(預設為 " ")
- string
- 處理字串的命令組
- subst ?-options? string
- 在字串中執行命令、變數或反斜槓替換
- switch ?-options? ?--? value alternatives
- 如果值匹配,則執行一個備選方案
- tell handle
- 返回檔案內部的位元組位置
- time body ?int?
- 執行 body int 次(預設 1),返回每次迭代使用了多少微秒
- trace
- 用於將操作繫結到變數或命令的命令組
- unset varName..
- 刪除給定的變數
- update ?idletasks?
- 服務事件
- uplevel ?level? body
- 在呼叫堆疊中向上評估 body
- upvar ?level? varName localVarName...
- 將給定的變數繫結到呼叫堆疊中的給定區域性變數。用於按引用呼叫,例如用於陣列
- variable varName ?value ?varName value...??
- 宣告變數在名稱空間中是非區域性的
- vwait varName
- 掛起執行,直到給定變數發生變化。如果事件迴圈尚未啟用,則啟動它
- while condition body
- 只要條件不為 0,就執行 body
Tcl 中的過程對應於其他語言中的過程、子程式或函式。它們始終返回一個結果(即使是空字串 ""),因此稱它們為函式可能最合適。但出於歷史原因,用於建立函式的 Tcl 命令稱為 **proc**,因此人們通常稱它們為過程。
proc name argumentlist body
示例
proc sum {a b} {return [expr {$a+$b}]}
return 是多餘的,因為 proc 在到達其末尾並返回其最後一個結果時會自動返回。
proc sum {a b} {expr {$a+$b}}
以下變體更加靈活,因為它接受任意數量的引數(特殊引數名 args 將所有剩餘引數收集到一個列表中,該列表是引數 args 的值)。
proc sum args {
set res 0
foreach arg $args {set res [expr {$res + $arg}]}
return $res
}
一個優雅但效率較低的替代方法是透過 join 使用加號連線 args 來構建字串,並將該字串提供給 expr。
proc sum args {expr [join $args +]}
如果 proc 定義中的引數是一個包含兩個元素的列表,則如果在呼叫中未給出第二個元素,則將其作為預設值(在本例中為 "Sir")。
proc greet {time {person Sir}} {return "good $time, $person"}
% greet morning John good morning, John % greet evening good evening, Sir
**內省:** 使用以下命令獲取所有已定義過程的名稱。
info procs
還有一些 **info** 子命令可以獲取過程的引數列表、可能的預設引數和主體。以下示例將它們結合起來,根據名稱重新建立過程的文字形式(corp 是 proc 的反向)。
proc corp name {
set argl {}
foreach arg [info args $name] {
if [info default $name $arg def] {lappend arg $def}
lappend argl $arg
}
list proc $name $argl [info body $name]
}
使用 **rename**,您可以過載任何命令,包括 C 編碼的命令。首先將原始命令重新命名為其他名稱,然後使用相同的簽名重新實現它,最終呼叫原始命令。例如,以下是一個過載的 proc,它報告是否多次使用相同的名稱定義了過程。
rename proc _proc
_proc proc {name argl body} {
if {[info procs $name] eq $name} {
puts "proc $name redefined in [info script]"
}
_proc $name $argl $body
}
**命名引數:** 命令的引數主要透過位置傳遞。但是,很容易新增 Python 或 Ada 中已知的行為,即引數可以在函式呼叫中命名,這可以更好地記錄程式碼,並允許以任意順序傳遞引數。
這個想法(正如在 Welch 的書中發現的那樣)是使用一個數組(這裡稱為 "" - "匿名陣列"),該陣列以引數名為鍵。最初,您可以設定一些預設值,並可能使用 proc 的引數覆蓋它們(該引數必須成對,即包含偶數個元素)。
proc named {args defaults} {
upvar 1 "" ""
array set "" $defaults
foreach {key value} $args {
if {![info exists ($key)]} {
set names [lsort [array names ""]]
error "bad option '$key', should be one of: $names"
}
set ($key) $value
}
}
用法示例
proc replace {s args} {
named $args {-from 0 -to end -with ""}
string replace $s $(-from) $(-to) $(-with)
}
測試
% replace suchenwirth -from 4 -to 6 -with xx suchxxirth % replace suchenwirth -from 4 -to 6 -witha xx bad option '-witha', should be one of: -from -to -with
通常,命令的引數按值傳遞(作為常量,或在變數名前面加上 $)。這可以安全地防止副作用,因為命令只會獲得值的副本,而無法更改變數。
但是,有時就是需要這樣。想象一下,您想要一個自定義命令將變數設定為零。在這種情況下,在呼叫時指定變數的名稱(不帶 $),並在 proc 中使用 **upvar** 將名稱(在範圍 "1 up" 中,即呼叫者的範圍)連結到本地變數。我通常在作為變數名的引數前面加上一個 _(例如 _var),並將 upvar 連結到沒有 _ 的相同名稱(例如 var)。
% proc zero _var {upvar 1 $_var var; set var 0}
% set try 42 42 % zero try 0 % set try 0
如果您經常使用按引用呼叫,您可以使用特殊模式(例如 &arg)來指示此類引數,並使用以下程式碼生成必要的 **upvar**。
proc use_refs { {char &}} {
foreach v [uplevel 1 {info locals}] {
if [string match $char* $v] {
uplevel 1 "upvar 1 \${$v} [string range $v 1 end]"
}
}
}
就是這樣。最好先在 proc 內部呼叫此命令,並對以特定字元開頭的所有引數進行 upvar 操作,預設字元為 "&" - 它執行類似於以下程式碼的程式碼
upvar 1 ${&foo} foo
在呼叫者的範圍內。測試
proc test_refs {a &b} {
use_refs
puts a=$a,b=$b
set b new_value
}
% set bar 42
42
% test_refs foo bar
a=foo,b=42
因此,a(按值傳遞)和 b(按引用傳遞)的值是可讀的;並且在呼叫者中更改 b 的副作用也發生了。
% set bar new_value
在過程內部,變數預設情況下是本地的。它們只存在於 proc 中,並在 return 時被清除。但是,您可以將本地變數繫結到呼叫堆疊中更高的變數(例如,在呼叫者中),直到最頂層的全域性範圍。
proc demo arg {
global g
set g 0 ;# will effect a lasting change in g
set local 1 ;# will disappear soon
set ::anotherGlobal 2 ;# another way to address a global variable
upvar 1 $arg myArg ;# make myArg point at a variable 1-up
set myArg 3 ;# changes that variable in the calling scope
}
還可以將命令定義為一個或多個單詞序列的別名,這些單詞將在執行之前替換它。(有趣的是 {} 引數是源和目標直譯器的名稱,它們通常是當前直譯器,由空字串 {} 或 "" 命名)。示例
interp alias {} strlen {} string length
interp alias {} cp {} file copy -force
內省:使用以下命令獲取所有已定義別名的名稱。
interp aliases
Tcl 是一種解釋型(加上即時位元組編譯)語言,因此直譯器當然是一種核心型別的物件。每次執行 Tcl 時,至少會執行一個直譯器,它接收指令碼並對其進行評估。
還可以建立額外的 "從屬" 直譯器來封裝資料和程序,這些直譯器又可以有它們自己的 "子從屬" 直譯器,依此類推,最終形成一個樹形層次結構。示例
% interp create helper
helper
% helper eval {expr 7*6}
42
% interp delete helper
% helper eval {expr 1+2}
invalid command name "helper"
透過刪除直譯器,所有全域性變數(以及名稱空間變數)也會被釋放,因此,如果需要,您可以使用它來進行模組化和封裝。
特別是,**安全直譯器** 故意限制了功能(例如,訪問檔案系統或 Web),因此來自 Web 的可能惡意程式碼無法造成重大破壞。
內省:以下命令列出當前直譯器的子直譯器("從屬")。
% interp slaves
整合(從 Tcl 8.5 開始),是指根據標準模式由子命令組成的命令。例如,Tcl 的內建 **chan** 和 **clock** 命令。子命令的排程以及對不存在子命令的提示性錯誤訊息都是內建的。子命令位於名為 "-map" 的 dict 結構中,包含交替的名稱和操作。非常簡單的示例
namespace ensemble create -command foo -map \
{bar {puts Hello} grill {puts World}}
建立了一個名為 foo 的命令,它可以像下面這樣呼叫。
% foo bar Hello % foo grill World % foo help unknown or ambiguous subcommand "help": must be foo, or bar
顯然,整合也是實現面向物件程式設計的一個很好的基礎,其中命令是物件的名稱,對映包含其方法。
**內省:** 使用以下命令序列化整合的對映。
namespace ensemble configure $name -map
名稱空間是用於存放過程、非區域性變數和其他名稱空間的容器。它們形成一個樹形結構,根位於名為 "::" 的全域性名稱空間。它們的名稱也使用 :: 作為分隔符,因此 ::foo::bar 是 ::foo 的子節點,::foo 是 :: 的子節點(類似於 Unix 上的路徑名,其中 / 既是分隔符又是根)。
簡而言之,名稱空間是一個單獨的區域,或者說是 範圍,過程和變數在該範圍內可見,並且對該範圍私有。
要建立名稱空間,只需在其中 eval 某些指令碼(可以為空)。
namespace eval ::foo {}
現在您可以使用它來定義過程或變數。
proc ::foo::test {} {puts Hello!}
set ::foo::var 42
要刪除名稱空間(並清理其所有變數、過程和子名稱空間),可以使用以下命令。
namespace delete ::foo
內省
namespace children :: info var namespace::* info commands namespace::*
以下程式碼給出了 Tcl 名稱空間(其中 ::,即全域性名稱空間,特別有趣 - 所有(孫)子節點也被新增)的變數和子節點所佔用的位元組大小的近似值。如果您多次呼叫此 proc,則可以觀察資料是否正在累積。
proc namespace'size ns {
set sum [expr wide(0)]
foreach var [info vars ${ns}::*] {
if {[info exists $var]} {
upvar #0 $var v
if {[array exists v]} {
incr sum [string bytelength [array get v]]
} else {
incr sum [string bytelength $v]
}
}
}
foreach child [namespace children $ns] {
incr sum [namespace'size $child]
}
set sum
}
用法示例
% puts [namespace'size ::] 179914
Tcl 使用者傳統上對執行緒(輕量級併發子程序)持懷疑態度 - 事件迴圈模型已被證明非常強大,並且更容易除錯。最初來自 Tk,事件迴圈已經遷移到 Tcl,並用於
- 檔案事件(比實際檔案更關注通道)
- 計時事件
- UI 事件(使用者進行的滑鼠或鍵盤操作)
但是,在 Tcl 構建中啟用執行緒的趨勢正在增長。底層模型是每個執行緒都在它自己的直譯器中執行,因此它基本上與外部世界隔離。執行緒之間的通訊必須使用顯式方法進行。
包是 Tcl 推薦的模組化軟體,尤其是支援庫。使用者最常使用的命令是
package require name ?version?
您可以使用純 Tcl 或作為擴充套件的包裝器來編寫包,擴充套件包括一個或多個已編譯的共享庫(以及可選的一個或多個 Tcl 指令碼)。流行的擴充套件包括
- BWidget(將有用的部件新增到 Tk - 更多內容見下文)
- Expect(支援透過網路進行遠端執行)
- Img(將對 Tk 新增對其他影像檔案格式的支援)
- snack(聲音輸入/輸出)
- Snit(OO 擴充套件,支援 Tk 中的 "超級部件")
- sqlite(一個微小但功能強大的 SQL 資料庫)
- tcllib(一個純 Tcl 包的集合 - 更多內容見下文)
- TclOO(從 8.5 開始的規範面向物件擴充套件)
- tcltcc(一個內建的 C 編譯器 - 更多內容見下文)
- TclX(系統相關擴充套件的集合,例如訊號處理)
- tdom(XML 解析器,SAX 或 DOM,帶有 XPath 查詢支援)
- Tk(跨平臺 GUI 工具包,更多內容見下文)
- tkcon(一個擴充套件了的功能豐富的控制檯)
- XOTcl(高階動態 OO 擴充套件)
以下指令碼建立了一個簡單的但有教育意義的包 futil,它在同名的名稱空間中實現了兩個用於讀取和寫入完整文字檔案的 proc,以及一個小的內省輔助函式 futil::?。註冊包(package provide)的命令僅在一切順利後才執行 - 這樣,有錯誤的原始碼,在包要求期間引發錯誤,將不會被註冊。(其他錯誤你必須自己發現並修復...)
常見的 Tcl 分發實踐有一個很好的習慣,即進行深入的測試,通常是在一個單獨的測試目錄中。另一方面,在同一個檔案中將自測試包含在程式碼中使編輯更容易,因此在 package provide 之後,只會在將此檔案作為頂層指令碼原始碼時執行的部分,它會練習在 futil 中定義的命令。是否應該將讀取的字串與寫入的字串相等是可爭議的 - 當前實現如果字串不以 \n 結尾,就會將 \n 附加到字串中,因為有些工具會抱怨或行為異常,如果它們沒有看到最後的換行符。
如果測試也沒有遇到任何錯誤,即使是包索引的必要構造也會被觸發 - 假設目錄中只包含一個包。否則,你最好刪除這些行,並自己處理索引建立。
使用此包的指令碼只需要包含這兩行
lappend ::auto_path <directory of this file> package require futil
如果你安裝(複製)包含原始碼和 pkgIndex.tcl 的目錄到 ${tcl_install_directory}/lib 下,你甚至可以省略第一行。
namespace eval futil {
set version 0.1
}
但現在回到組成包的單個指令碼(將其儲存為 futil.tcl 會更有意義)。我們在 futil 名稱空間中提供了一個 read 和一個 write 函式,外加一個小的內省函式 ?,它返回可用函式的名稱
proc futil::read {filename} {
set fp [open $filename]
set string [::read $fp] ;# prevent name conflict with itself
close $fp
return $string
}
proc futil::write {filename string} {
set fp [open $filename w]
if {[string index $string end]!="\n"} {append string \n}
puts -nonewline $fp $string
close $fp
}
proc futil::? {} {lsort [info procs ::futil::*]}
# If execution comes this far, we have succeeded ;-)
package provide futil $futil::version
#--------------------------- Self-test code
if {[info ex argv0] && [file tail [info script]] == [file tail $argv0]} {
puts "package futil contains [futil::?]"
set teststring {
This is a teststring
in several lines...}
puts teststring:'$teststring'
futil::write test.tmp $teststring
set string2 [futil::read test.tmp]
puts string2:'$string2'
puts "strings are [expr {$teststring==$string2? {}:{not}}] equal"
file delete test.tmp ;# don't leave traces of testing
# Simple index generator, if the directory contains only this package pkg_mkIndex -verbose [file dirn [info scr]] [file tail [info scr]] }
Tcllib
[edit | edit source]Tcllib 是一個純 Tcl 包的集合。它可以從 sourceForge 獲取,但也是 ActiveTcl 的一部分。以下包含的包列表可能不完整,因為 Tcllib 正在不斷增長...
- aes - 高階加密標準。
- asn - asn.1 BER 編碼器/解碼器
- http/autoproxy - 用於自動使用 HTTP 代理伺服器的程式碼
- base64 - 字串和檔案的 Base64 編碼和解碼。
- bee - BitTorrent 序列化編碼器/解碼器。
- bibtex - Neil Madden 的 bibtex 檔案解析器。尚未完全完成,因此未設定為安裝。
- calendar - 日曆操作(參見 tcllib 日曆模組)。
- cmdline - 各種形式的命令列和選項處理。
- comm - 基於套接字的程序間通訊。模擬 Tk 的 send 命令的形式。
- control - 用於 tcl 流程結構的程式,如 assert、do/until、do/while、no-op
- counter - 用於計數器和直方圖的程式
- crc - 計算字串和檔案的各種 CRC 校驗和。
- csv - 操作逗號分隔值資料
- des - 資料加密標準。 ::DES::des (尚未安裝)
- dns - 與域名系統互動。 dns::address、dns::cleanup、dns::cname、dns::configure、dns::name、dns::reset、dns::resolve、dns::status、dns::wait,
- doctools - 用於以簡單但強大的格式編寫手冊頁/文件的系統。
- exif - exif::analyze exif::fieldnames
- fileutil - 用於操作檔案的實用程式,模擬各種 unix 命令列應用程式(cat、find、file(type)、touch、...)。
- ftp - FTP(檔案傳輸協議)的客戶端實現。迫切需要重寫。
- ftpd - FTP 的伺服器端實現
- grammar_fa - 對有限自動機進行操作。
- html - 從 Tcl 指令碼生成 HTML。 html::author、html::author、html::bodyTag、html::cell、html::checkbox、html::checkSet、html::checkValue、html::closeTag、html::default、html::description、html::description、html::end、html::eval、html::extractParam、html::font、html::for、html::foreach、html::formValue、html::getFormInfo、html::getTitle、html::h、html::h1、html::h2、html::h3、html::h4、html::h5、html::h6、html::hdrRow、html::head、html::head、html::headTag、html::if、html::init、html::init、html::keywords、html::keywords、html::mailto、html::meta、html::meta、html::minorList、html::minorMenu、html::openTag、html::paramRow、html::passwordInput、html::passwordInputRow、html::radioSet、html::radioValue、html::refresh、html::refresh、html::row、html::select、html::selectPlain、html::set、html::submit、html::tableFromArray、html::tableFromList、html::tagParam、html::textarea、html::textInput、html::textInputRow、html::title、html::title、html::urlParent、html::varEmpty、html::while,
- htmldoc - 這不是一個真正的模組,而是 tcllib 1.3 安裝 tcllib 文件的 HTML 格式的地方。
- htmlparse - 用於允許對包含 HTML 的字串進行有限操作的程式。 ::htmlparse::parse、 ::htmlparse::debugCallback、 ::htmlparse::mapEscapes、 ::htmlparse::2tree、 ::htmlparse::removeVisualFluff、 ::htmlparse::removeFormDefs,
- ident - RFC 1413 ident 客戶端協議實現
- imap4 - 當前用於與 IMAP 伺服器互動的未記錄程式碼
- inifile - 用於操作初始化檔案的程式碼。 ::ini::open、 ::ini::close、 ::ini::commit、 ::ini::sections、 ::ini::keys、 ::ini::value
- dns/ip - IP 地址的操作。 ::ip::version、 ::ip::is、 ::ip::normalize、 ::ip::equal、 ::ip::prefix
- irc - 網際網路中繼聊天程式。 irc::config、irc::connection,
- javascript - 生成 Javascript 以包含在 HTML 頁面中。 javascript::BeginJS、javascript::EndJS、javascript::MakeMultiSel、javascript::MakeClickProc、javascript::makeSelectorWidget、javascript::makeSubmitButton、javascript::makeProtectedSubmitButton、javascript::makeMasterButton、javascript::makeParentCheckbox、javascript::makeChildCheckbox
- jpeg - 編輯註釋塊,獲取 JPG 格式影像的尺寸和資訊,讀取影像的 exif 資料
- ldap - LDAP(輕量級目錄訪問協議)的客戶端實現。
- log - 用於將日誌條目新增到檔案的通用程式。 ::log::levels、 ::log::logMsg、 ::log::lv2longform、 ::log::lv2color,::log::lv2priority,
- logger - ::logger::walk、 ::logger::services、 ::logger::enable、 ::logger::disable (日誌模組的一部分)
- math - 通用數學程式。 ::math::calculus、 ::math::combinatorics、 ::math::cov、 ::math::fibonacci、 ::math::integrate、 ::math::interpolate、 ::math::max、 ::math::mean、 ::math::min、 ::math::optimize、 ::math::product、 ::math::random、 ::math::sigma、 ::math::statistics、 ::math::stats、 ::math::sum
- md4 - ::md4::md4、 ::md4::hmac、 ::md4::MD4Init、 ::md4::MD4Update、 ::md4::MD4Final
- md5 - [填寫此模組的描述] ::md5::md5、 ::md5::hmac、 ::md5::test、 ::md5::time、 ::md5::<<<
- md5crypt - ::md5crypt::md5crypt、 ::md5crypt::aprcrypt
- mime - ::mime::initialize、 ::mime::parsepart、 ::mime::finalize、 ::smtp::sendmessage
- multiplexer - [填寫外部介面]
- ncgi - 用於 CGI 應用程式的程式。 ::ncgi::reset、 ::ncgi::urlStub、 ::ncgi::urlStub
- nntp - 用於與 Usenet 新聞伺服器互動的例程。 ::nntp::nntp、 ::nntp::NntpProc、 ::nntp::NntpProc、 ::nntp::okprint、 ::nntp::message,
- ntp - 網路時間協議程式 ::ntp::time
- png - 編輯註釋塊,獲取可移植網路圖形格式的影像尺寸和資訊。
- pop3 - 用於從 pop3 伺服器讀取郵件的郵局協議函式。 ::pop3::open、 ::pop3::close、 ::pop3::status,
- pop3d - 郵局協議伺服器。 pop3d::new
- profiler - ::profiler::tZero、 ::profiler::tMark、 ::profiler::stats、 ::profiler::Handler、 ::profiler::profProc、 ::profiler::init
- rc4 - 流加密。 ::rc4::rc4
- report - 以各種報告樣式格式化文字。 ::report::report , ::report::defstyle、 ::report::rmstyle,
- sha1 - ::sha1::sha1、 ::sha1::hmac
- smtpd - ::smtpd::start、 ::smtpd::stop、 ::smtpd::configure、 ::smtpd::cget
- snit - Snit's Not Incr Tcl - OO 包。基於委託。 ::snit::type、 ::snit::widget、 ::snit::widgetadaptor
- soundex::knuth - 基於字母理論發音的字串匹配
- stooop - OO 包。 stooop::class、stooop::virtual、stooop::new、stooop::delete、stooop::classof
- struct1 - struct 的版本 1(見下文),為向後相容性提供。
- struct::list、 ::struct::graph、 ::struct::matrix、 ::struct::queue、 ::struct::stack、 ::struct::Tree、 ::struct::record、 ::struct::skiplist、 ::struct::prioqueue,新建: ::struct::sets
- tar - 解壓縮、列出和統計 tar 包中的檔案,以及建立新的 tar 包
- textutil - 用於處理大量文字的實用程式。 textutil::expand - expand 宏處理器的核心。
- tie - Tcl 陣列的永續性。
- treeql - 樹查詢語言,靈感來自 COST。
- uri - 處理 uri/url(拆分、合併、...)
- uuid - 建立唯一識別符號。
TclOO
[edit | edit source]TclOO 是一個可載入的包,用於提供面向物件程式設計的基礎,旨在使 Itcl、Snit 或 XOTcl 等特定 OO 風格能夠構建在它之上。但它本身也是一個可用的 OO 系統,提供類、多重繼承、mixin 和過濾器。以下是一些示例程式碼,讓你瞭解一下
#!/usr/bin/env tclsh85
package require TclOO
namespace import oo::*
class create Account {
constructor { {ownerName undisclosed}} {
my variable total overdrawLimit owner
set total 0
set overdrawLimit 10
set owner $ownerName
}
method deposit amount {
my variable total
set total [expr {$total + $amount}]
}
method withdraw amount {
my variable {*}[info object vars [self]] ;# "auto-import" all variables
if {($amount - $total) > $overdrawLimit} {
error "Can't overdraw - total: $total, limit: $overdrawLimit"
}
set total [expr {$total - $amount}]
}
method transfer {amount targetAccount} {
my variable total
my withdraw $amount
$targetAccount deposit $amount
set total
}
destructor {
my variable total
if {$total} {puts "remaining $total will be given to charity"}
}
}
tcltcc
[edit | edit source]Tcltcc 是一個可載入的包,它包裝了 Tiny C 編譯器 (tcc) 以供 Tcl 使用。它可以用於
- 將 C 程式碼直接編譯到記憶體中
- 生成動態載入庫 (DLL) 或可執行檔案。
便利函式生成包裝程式碼,因此使用者只需編寫真正重要的 C 程式碼。
示例
將 C 函式“動態地”包裝到 Tcl 命令中(此處在互動式會話中顯示)
% package require tcc
0.2
% namespace import tcc::*
% cproc sigmsg {int i} char* {return Tcl_SignalMsg(i);}
% sigmsg 4
illegal instruction
生成一個帶有快速實現的斐波那契數的 DLL
% set d [tcc::dll]
% $d ccode {
static int fib(int n) {return n <= 2? 1 : fib(n-1) + fib(n-2);}
}
% $d cproc fiboy {int n} int {return fib(n);}
% $d write -name fiboy
% load fiboy[info sharedlibextension]
% fiboy 20
6765
生成一個帶有額外的 square 命令的 tclsh
% set code [tcc::wrapCmd square {double x} double x_square {return x*x;}]
% append code {
int AppInit(Tcl_Interp *interp) {
int rc;
rc = Tcl_CreateObjCommand(interp,"square",x_square,NULL,NULL);
return Tcl_Init(interp);
}
int main(int argc, char *argv[]) {
Tcl_Main(argc, argv, AppInit);
return 0;
}
}
% tcc $::tcc::dir exe t
% t add_file $::tcc::dir/c/crt1.c
% t add_library tcl8.5
% t compile $code
% t output_file mytclsh.exe
% exec mytclsh.exe {<<puts [square 5]}
25.0
Tcltcc 是開源的,LGPL 許可的,可從 http://code.google.com/p/tcltcc/ 獲取。在當前早期階段(2007 年 10 月),完整的功能僅在 Windows 95/XP 平臺上可用,但記憶體中編譯在 Linux 上也可以工作。
tDOM
[edit | edit source]tDOM 是一個用於 XML/HTML 處理的流行擴充套件,它允許 SAX 風格的“即時”解析和 DOM 方法,在記憶體中表示整個 XML 元素。
這是一個 SAX 風格應用程式的例子。隨 tDOM 附帶的 expat 解析器使用回撥來處理元素開始、字元資料和處理指令。元素、屬性、字元和處理指令都進行了計數,此外還對每種元素型別進行了計數。
#!/usr/bin/env tclsh
package require tdom
#--- Callbacks for certain parser events
proc el {name attlist} {
global g
incr ::nEl
incr ::nAtt [llength $attlist]
inc g($name)
}
proc ch data {
incr ::nChar [string length $data]
}
proc pi {target data} {
incr ::nPi
}
proc inc {varName {increment 1}} {
upvar 1 $varName var
if {![info exists var]} {set var 0}
incr var $increment
}
#--- "main" loop
if ![llength $argv] {puts "usage: $argv0 file..."}
foreach file $argv {
foreach i {nEl nAtt nChar nPi} {set $i 0} ;# reset counters
array unset g
set p [expat -elementstartcommand el \
-characterdatacommand ch \
-processinginstructioncommand pi ]
if [catch {$p parsefile $file} res] {
puts "error:$res"
} else {
puts "$file:\n$nEl elements, $nAtt attributes, $nChar characters,\
$nPi processing instructions"
foreach name [lsort [array names g]] {
puts [format %-20s%7d $name $g($name)]
}
}
$p free
}