Tcl允許你使用「程序」覆寫已經存在的命令,或是新增自己定義的命令,簡單的說如果你認為Tcl裡現有的命令不夠使用,或是不好用,那你可以使用程序重新實作那些令你覺得不滿意的命令,或是定義新的命令以擴充功能。本篇文章介紹Tcl定義程序及使用程序的方式。
8.1 定義程序
程序在使用前必需先行定義,當新的程序定義好之後就可以像Tcl內建的命令一樣使用它。定義程序有兩個注意事項:- 新的程序必需要有一個名稱,若名稱和其它程序或Tcl命令重複的話,最後一個定義的程序會蓋掉重覆名稱的其它程序及Tcl命令。
- 新定義的程序需要像Tcl的命令一樣,可以帶入參數來調整程序執行的行為。
如下是定義程序的語法:
proc name args body
name是新程序的名稱,你可以自行指定一個有意義的文字串。args稱之為參數清單,所有被帶入程序的參數都會被依序儲存在參數清單裡面,如果你不想讓程序有帶入參數的功能,那麼args必需指定為空字串。body是呼叫程序時要被執行程式碼,注意!! body內的程式碼在定義程序時並不會馬上被執行,而是等到呼叫程序時才會執行。另外,只要是在body內的程式碼都可以使用參數清單上所有的變數。以下是一個簡單的例子:
這個程式定義了一個名為add的程序,add可以接受兩個參數,接收到的參數會依序儲存在op1及op2變數裡。第2行是程序的主體,執行時expr會把op1及op2兩變數的值相加然後透過puts命令輸出。程式的第4~6行的動作稱之為呼叫程序,它就和使用Tcl內建的命令一樣。在第4行裡呼叫add程序時5及6會帶入op1及op2兩個變數,第5及6行也是以此類推。
程式執行結果:
11 5 3
不帶參數的程序可以這樣寫:
程式輸出:
Hi! 大家好
□ 覆寫已儲存的命令
事實上除非是很特殊的情況,否則真很少會去複寫Tcl內建的命令,建議大家請別這麼做。但如果你真的確定要這麼做的話,下面是一個簡單的例子,它複寫了內建的gets命令,而且把它變成輸出的命令:程式輸出:
xxx
§ 關於程序裡的變數
一般的情況下如果沒有特別指定變數的作用範圍,所有在程序內建立的變數,都屬於區域性質的變數,它們都只能在程序內使用。
§ 為什麼要使用程序
程序有兩個很重要的特色,分別是 (1)程序只要定義一次,就可以使用任意次 (2)程序可以把較大的程式切割成許多較小的小命令。前者的特色,時常被應用來撰寫需要重複使用的功能,例如,你在設計一個文字編輯器的程式的時候,把「開檔案」的功能寫成程序就是一個好方法,因為它常常會被使用。而後者的特色在寫大程式時特別重要,因為把大的程式切割成許多小命令撰寫,會更利於程式的維護及修改,至於如何把程式漂亮的切開,這就要時間及經驗的累積了。
8.2 程序回傳值
程序可以使用return命令來回傳執行結果,被回傳的值可以用來當作命令代換的結果。下方的程式是一個計算1+2+...+N的程序,它會回傳累加後的結果。上方的sum程序可以接受一個參數,並計算1+2+....$val的值。程式的第6行使用return把計算的結果回傳,回傳的值將被用來代換第8行的子命令。注意!! 只要在程序主體中遇到return命令,return會立刻把跟在自己後面的參數值回傳並結束程序。如果return後面沒有帶任何參數相當於回傳空字串,另外若是程序中沒有出現return命令,預設會回傳程序裡最後一個命令的回傳值。
程式輸出:
15
8.3 指定參數的預設值
Tcl允許你設定參數的預設值,被指定了預設值的參數,呼叫程序時可以選擇性的輸入,例如下方程式的第二個參數val2設定了預設值1,所以呼叫程序時第2個參數可以選擇性的附加,如果呼叫add時沒有給予第2個參數,那val2的預設值就是1。 程式執行結果:
7 6
注意!! 如果在程序的參數清單中第i個項目指定了預設值,那麼第i個項目以後的所有項目也都要指定預設值,例如下面是錯誤的語法,因為val2指定了預設值但val3沒有。
8.4 不固定數量的參數
Tcl還可以讓程序接受不固定數量的參數,只要參數清單的最後一個參數命名為args,如此一來Tcl會把多帶入的參數以清單的方式儲存在args變數中。注意!! 這裡的args是指參數清單最後一個變數名稱剛好是args,並不是proc語法中的args參數。以下是一個不定參數的例子:我們把add改成可以接受1~N個參數,而且會把所有帶入的參數做相加的動作。例如:程式的第9行帶入6個參數,其中1會設定給參數清單中的val,其餘的2~6會以清單的格式儲存在args中。程式的3~5行使用foreach迴圈命令逐一取出儲存於args中的項目,並把它們累加到result變數中。 程式執行結果:
3 21
8.5 參數傳遞的細節
Tcl預設使用「傳值」的方式把呼叫程序時附加的參數傳遞給參數清單。「傳值」簡單的說就是複製參數值的意思,比如下方程式第6行的變數v,它的值會複製一份給參數清單中的val1,它們是獨立的個體彼此不會影響,因此就算第2行把val1的值加上100,第7行列印出來的值仍然是100。程式執行結果:
val1 = 200 v = 100
按右上方的「#」號切換側邊欄