国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
Tcl: 一個(gè)可嵌入的命令語(yǔ)言
John K. Ousterhout
Computer Science Division
Electrical Engineering and Computer Sciences
University of California at Berkeley
Berkeley, CA 94720
ouster@sprite.berkeley.edu
翻譯:寒蟬退士
譯者聲明:譯者對(duì)譯文不做任何擔(dān)保,譯者對(duì)譯文不擁有任何權(quán)利并且不負(fù)擔(dān)任何責(zé)任和義務(wù)。
摘要
Tcl 是用于工具命令語(yǔ)言的一個(gè)解釋器。它由作為基本命令解釋器嵌入到工具(比如編輯器、調(diào)試器
等)中的一個(gè)庫(kù)包組成。Tcl 提供了(a)用于簡(jiǎn)單的文本命令語(yǔ)言的分析器,(b)一組內(nèi)置的實(shí)用命令,
和(c)一個(gè) C 接口,工具通過(guò)它用特定于工具的命令增加內(nèi)置命令。Tcl 在與窗口組件庫(kù)整合的時(shí)候
特別有吸引力:它通過(guò)了提供變量、過(guò)程、表達(dá)式等機(jī)制增進(jìn)了組件的可編程性;它允許用戶(hù)編程
組件的外觀(guān)和動(dòng)作二者;并且它在交互式程序之間提供一個(gè)簡(jiǎn)單但強(qiáng)力的通信機(jī)制。
本文出現(xiàn)于 1990 Winter USENIX Conference Proceedings
1. 介紹
Tcl 代表了“tool command language - 工具命令語(yǔ)言”。它由一個(gè)庫(kù)包組成,程序可以把它用作自己的命令
語(yǔ)言的基礎(chǔ)。Tcl 的開(kāi)發(fā)由兩項(xiàng)觀(guān)察所推動(dòng)。第一項(xiàng)觀(guān)察是,通用可編程命令語(yǔ)言通過(guò)允許用戶(hù)用命令語(yǔ)言
寫(xiě)程序來(lái)擴(kuò)展工具的內(nèi)置設(shè)施,從而擴(kuò)大了工具的能力。在強(qiáng)力的命令語(yǔ)言之中最眾所周知的例子是 UNIX
shell[5] 和 Emacs 編輯器[8]。在各自情況下,出現(xiàn)的有著不同尋常能力的計(jì)算環(huán)境,在很大程度上是因?yàn)?div style="height:15px;">
能獲得可編程的命令語(yǔ)言。
第二個(gè)促成它的觀(guān)察是交互式應(yīng)用正在增長(zhǎng)。在 1970 年代晚期和 1980 年代早期的分時(shí)環(huán)境中,幾乎所有
的程序都是面向批處理的。典型的使用交互式的命令 shell 來(lái)調(diào)用它們。除了 shell 之外,只有少數(shù)其他的
程序是交互式的,比如編輯器和郵件器。正好相反,今天使用的個(gè)人工作站,帶有它們自己的光柵顯示器和
鼠標(biāo),鼓勵(lì)了一種不同的系統(tǒng)結(jié)構(gòu),在這里大量的程序是交互式的,并且最常見(jiàn)的交互方式是直接用鼠標(biāo)操
縱單獨(dú)的應(yīng)用。此外,今天能獲得的大顯示器使很多交互式的應(yīng)用立即活躍起來(lái)成為可能,而對(duì)于在十年前
很小的屏幕這是不實(shí)際的。
不幸的是,很少的今天的交互式程序擁有 shell 或 Emacs 命令語(yǔ)言的能力。在這里好的命令語(yǔ)言是存在著
的,它們趨向與特定的程序捆綁在一起。每個(gè)新的交互式程序都要求開(kāi)發(fā)一個(gè)新的命令語(yǔ)言。在多數(shù)情況
下,應(yīng)用程序員沒(méi)有時(shí)間或愛(ài)好去實(shí)現(xiàn)一個(gè)通用設(shè)施(特別是在應(yīng)用自身很簡(jiǎn)單的時(shí)候),所以結(jié)果的命令
語(yǔ)言趨向于帶有不充分的功能和笨拙的語(yǔ)法。
Tcl 是一個(gè)獨(dú)立于應(yīng)用的命令語(yǔ)言。它作為一個(gè) C 庫(kù)包存在,可以用于很多不同的程序中。Tcl 庫(kù)提供了
用于簡(jiǎn)單但完全可編程的命令語(yǔ)言的一個(gè)分析器。這個(gè)庫(kù)還實(shí)現(xiàn)了提供了通用的編程構(gòu)造的一組內(nèi)置命令,
比如變量、列表、表達(dá)式、條件、循環(huán)和過(guò)程。單個(gè)的應(yīng)用程序可以用特定于應(yīng)用的命令來(lái)擴(kuò)展基本的
Tcl 語(yǔ)言。Tcl 庫(kù)還提供一組實(shí)用工具例程來(lái)簡(jiǎn)化特定于工具的命令的實(shí)現(xiàn)。
我相信 Tcl 在窗口環(huán)境中是特別有用的,它提供了兩項(xiàng)優(yōu)勢(shì)。首先,它可以用做編制應(yīng)用的界面的一個(gè)通用
機(jī)制。如果一個(gè)工具基于 Tcl,則應(yīng)當(dāng)相對(duì)容易的去修改應(yīng)用的用戶(hù)界面,并使用新命令來(lái)擴(kuò)展這個(gè)界面。
其次和更重要的是,Tcl 為工具之間通信提供一種統(tǒng)一的框架。如果在所有的工具中統(tǒng)一使用了它,Tcl 將
使工具在一起工作得比今天的狀況更加優(yōu)雅。
本文余下部分組織如下:第 2 節(jié)描述用戶(hù)見(jiàn)到的 Tcl 語(yǔ)言。第 3 節(jié)討論在應(yīng)用程序中如何使用 Tcl,包括在
應(yīng)用程序和 Tcl 庫(kù)之間的 C 語(yǔ)言接口。第 4 節(jié)描述在窗口環(huán)境中如何使用 Tcl 來(lái)定制界面動(dòng)作和外觀(guān)。第 5
節(jié)展示如何使用 Tcl 作為進(jìn)程間通信的媒介,和為什么這很重要。第 6 表述 Tcl 實(shí)現(xiàn)的狀態(tài)和一些初步的
性能測(cè)量。第 7 節(jié)把 Tcl 與 Lisp、Emacs 和 NeWS 做對(duì)比,第 8 節(jié)總結(jié)本文。
2. Tcl 語(yǔ)言
在某種意義上,Tcl 語(yǔ)言的語(yǔ)法是不重要的:任何編程語(yǔ)言,不管它是 C[6]、Forth[4]、Lisp[1] 還是
Postscript[2] 都可以提供同 Tcl 大體相同的可編程性和通信上的優(yōu)勢(shì)。這提示了最佳實(shí)現(xiàn)途徑是借用現(xiàn)存的
語(yǔ)言,并集中于為使用這門(mén)語(yǔ)言提供一個(gè)方便的框架。但是,可嵌入的命令語(yǔ)言的所處環(huán)境對(duì)語(yǔ)言提出了一
組不同尋常的約束,后面將描述它們。我最終決定了從頭設(shè)計(jì)一個(gè)新語(yǔ)言更有可能滿(mǎn)足這些約束,并比現(xiàn)存
的語(yǔ)言帶有更少的實(shí)現(xiàn)努力。
Tcl 是不尋常的因?yàn)樗峁﹥煞N不同的接口: 給用戶(hù)發(fā)起 Tcl 命令的一個(gè)文本接口,和給它所嵌入的應(yīng)用的
一個(gè)過(guò)程接口。這些接口的每個(gè)都必須是簡(jiǎn)單的、強(qiáng)力的和高效的。在語(yǔ)言設(shè)計(jì)中有四個(gè)主要的因素:
[1] 語(yǔ)言用于命令。幾乎所有 Tcl“程序”都是短小的,很多只有一行長(zhǎng)。多數(shù)程序?qū)⑹擎I入的,執(zhí)行一
次或者幾次,接著就丟棄了。這提示了這門(mén)語(yǔ)言應(yīng)當(dāng)有一個(gè)簡(jiǎn)單的語(yǔ)法,以便于鍵入命令。多數(shù)現(xiàn)存
的編程語(yǔ)言都有復(fù)雜的語(yǔ)法;在寫(xiě)長(zhǎng)程序的時(shí)候有益,但如果用做命令語(yǔ)言就笨拙了。
[2] 語(yǔ)言必須是可編程的。它應(yīng)當(dāng)包含通用編程構(gòu)造,比如變量、過(guò)程、條件和循環(huán),這樣用戶(hù)可以
通過(guò)寫(xiě) Tcl 過(guò)程來(lái)擴(kuò)展內(nèi)置的命令??蓴U(kuò)展性也要求簡(jiǎn)單的語(yǔ)法:這使 Tcl 程序生成其他 Tcl 程序
變得容易了。
[3] 語(yǔ)言必須允許一個(gè)簡(jiǎn)單而高效的解釋器。由于 Tcl 庫(kù)要包含到許多小程序中,特別是在沒(méi)有共享庫(kù)
的機(jī)器上,解釋器必須不占用太多的內(nèi)存。用來(lái)解釋 Tcl 命令的機(jī)制必須足夠快,可用于每秒發(fā)生上
百次的事件,比如鼠標(biāo)移動(dòng)。
[4] 語(yǔ)言必須允許對(duì) C 應(yīng)用的一個(gè)簡(jiǎn)單接口。它必須易于讓 C 應(yīng)用調(diào)用這個(gè)解釋器,并易于讓它們用
特定于應(yīng)用的命令來(lái)擴(kuò)展內(nèi)置的命令。這個(gè)因素是我決定不使用 Lisp 作為命令語(yǔ)言的原因之一:
Lisp 的基本數(shù)據(jù)類(lèi)型和存儲(chǔ)管理機(jī)制與 C 實(shí)在是不同,很難在它們之間建立清晰而簡(jiǎn)單的接口。對(duì)
Tcl 我使用了對(duì)于 C 最自然的數(shù)據(jù)類(lèi)型(字符串)。
2.1. Tcl 語(yǔ)言語(yǔ)法
Tcl 的基本語(yǔ)法類(lèi)似于 UNIX shell:命令由用空格或 TAB 分隔的一個(gè)或多個(gè)字段組成。第一個(gè)字段是命令
的名字,它可以是內(nèi)置命令、特定于應(yīng)用的命令、或者是由一系列的 Tcl 命令組成的過(guò)程。在第一個(gè)后面
的字段都作為參數(shù)傳遞給命令。如同在 UNIX shell 中那樣,換行字符用做命令分隔符,分號(hào)也可用來(lái)分隔
在同一行上的命令。不同于 UNIX shell,每個(gè) Tcl 命令返回一個(gè)字符串結(jié)果,或者是空串,如果不適宜返回
值的話(huà)。
在 Tcl 中有四個(gè)補(bǔ)充的語(yǔ)法構(gòu)造,它們給予語(yǔ)言一種類(lèi)似 Lisp 的風(fēng)格。使用花括號(hào)來(lái)組合復(fù)雜的參數(shù);它
們充當(dāng)可嵌套的引用字符。如果參數(shù)的第一個(gè)字符是左花括號(hào),則這個(gè)參數(shù)不以空白終結(jié)。轉(zhuǎn)而,它終結(jié)于
相匹配的右花括號(hào)。傳遞給這個(gè)命令的參數(shù)由在花括號(hào)中間的所有東西組成,并剝除圍繞的花括號(hào)。例如,
命令
set a {dog cat {horse cow mule} bear}
將收到兩個(gè)參數(shù):“a”和“dog cat {horse cow mule} bear”。這個(gè)特定命令將把變量 a 設(shè)置為等于第二個(gè)參數(shù)
的一個(gè)字符串。如果參數(shù)包圍在花括號(hào)中,則不對(duì)這個(gè)參數(shù)做下面描述的其他替換。花括號(hào)最常見(jiàn)的用途是
把一個(gè) Tcl 子程序指定為到 Tcl 命令的參數(shù)。
在 Tcl 中第二個(gè)語(yǔ)法構(gòu)造是是方括號(hào),它用于引發(fā)命令替換。如果在參數(shù)中出現(xiàn)了左方括號(hào),則從這個(gè)左方
括號(hào)一直到相匹配的右方括號(hào)的所有東西都作為一個(gè)命令來(lái)對(duì)待,并由 Tcl 解釋器遞歸的執(zhí)行。命令的結(jié)果
接著替換到這個(gè)方括號(hào)包圍的字符串所在的位置上。例如,考慮命令
set a [format {Santa Claus is %s years old} 99]
format 命令做類(lèi)似 printf 的格式化并返回字符串“Santa Claus is 99 years old”,接著把它傳遞給 set 并賦值
到變量 a。第三個(gè)語(yǔ)法構(gòu)造是美元號(hào),它用于變量替換。如果它出現(xiàn)在參數(shù)中,則隨后的字符作為變量的名
字對(duì)待;變量的內(nèi)容被替換到參數(shù)中這個(gè)美元符號(hào)和名字所在的位置上。例如,命令
set b 99
set a [format {Santa Claus is %s years old} $b]
導(dǎo)致 a 有同前面段落中的簡(jiǎn)單命令相同的最終值。變量替換不是嚴(yán)格必須的,因?yàn)橛衅渌绞絹?lái)達(dá)到相同的
效果,但是它減少了鍵入。
最后一個(gè)語(yǔ)法構(gòu)造是反斜杠字符,可以用它把特殊字符插入到參數(shù)中,比如花括號(hào)或非打印字符。
2.2. 數(shù)據(jù)類(lèi)型
在 Tcl 中只有一種數(shù)據(jù)類(lèi)型:字符串。所有命令、到命令的參數(shù)、命令返回的結(jié)果和變量的值都是 ASCII
字符串。Tcl 始終使用字符串便于在 Tcl 庫(kù)過(guò)程和包圍它的應(yīng)用的 C 代碼之間來(lái)回傳遞信息。這使它易于在
不同類(lèi)型的機(jī)器之間來(lái)回傳遞有關(guān) Tcl 的信息。
盡管在 Tcl 中所有的東西都是字符串,很多命令都希望它們的字符串參數(shù)有特定的格式。這里的字符串有三
種特定的通用格式:列表、表達(dá)式和命令。列表只是包含用空白分隔的一個(gè)或多個(gè)字段的字符串,類(lèi)似于
命令??梢允褂没ɡ▉?lái)包圍復(fù)雜的列表元素;這些復(fù)雜的列表元素自身經(jīng)常也是列表,類(lèi)似于 Lisp。例如,
字符串
dog cat {horse cow mule} bear
是有四個(gè)元素的一個(gè)列表,其中第三個(gè)元素是有三個(gè)元素的列表。Tcl 提供一組列表操縱的命令,比如建立
列表、提取元素、和計(jì)算列表長(zhǎng)度。
字符串的第二種常見(jiàn)形式是數(shù)值表達(dá)式。Tcl 表達(dá)式同 C 中的表達(dá)式有著同樣的操作符合優(yōu)先級(jí)。Tcl 命令
expr 把字符串作為表達(dá)式來(lái)求值并返回結(jié)果(當(dāng)然是作為字符串)。例如,命令
expr {($a < $b) || ($c != 0)}
在變量 a 小于變量 b 或者變量 c 是零的時(shí)候返回“1”,否則返回“0”。一些其他的命令,比如 if 和 for, 期望它
們的一個(gè)或多個(gè)參數(shù)是表達(dá)式。
字符串的第三種常見(jiàn)解釋是命令(或命令的序列)。這種形式的參數(shù)用在實(shí)現(xiàn)控制結(jié)構(gòu)的 Tcl 命令中。例如,考慮下列命令:
if {$a < $b} {
set tmp $a
set a $b
set b $tmp
}
這里的 if 命令接受兩個(gè)參數(shù),每個(gè)都是用花括號(hào)界定的。If 是內(nèi)置命令,它把它的第一個(gè)參數(shù)作為表達(dá)式來(lái)
求值;如果結(jié)果非零,則 if 把它的第二個(gè)參數(shù)作為 Tcl 命令執(zhí)行。這個(gè)特定命令在變量 a 小于 b 的時(shí)候交換
a 和 b 的值。
Tcl 還允許用戶(hù)定義用 Tcl 語(yǔ)言寫(xiě)的命令過(guò)程。我稱(chēng)謂這些過(guò)程為 tclproc,為的是區(qū)別于用 C 寫(xiě)成的其他
過(guò)程。使用 proc 內(nèi)置命令來(lái)建立 tclproc。例如,下面定義了一個(gè)遞歸的階乘過(guò)程的 Tcl 命令:
proc fac x {
if {$x == 1} {return 1}
return [expr {$x * [fac [expr $x-1]]}]
}
proc 命令接受三個(gè)參數(shù):新 tclproc 的名字、一個(gè)變量名字的列表(在這個(gè)實(shí)例中試只有一個(gè)元素 x 的列表),
和一個(gè)構(gòu)成 tclproc 的過(guò)程體的 Tcl 命令。一旦執(zhí)行了這個(gè) proc 命令,fac 就可以同其他 Tcl 命令一樣調(diào)用
了。例如
fac 4
將返回字符串“24”。
控制
catch, error, info, time
雜項(xiàng)
exec
調(diào)用子進(jìn)程
file, glob, print, source
文件操縱
format, scan, string
字符串操縱
expr
表達(dá)式
concat, index, length, list, range
列表操縱
global, proc, return, set
變量和過(guò)程
break, case, continue, eval, for, foreach, if
圖表 1。內(nèi)置的 Tcl 命令。這是對(duì)使用 Tcl 的任何應(yīng)用都能獲得的一組命令。應(yīng)用可以定義額外的命令。
圖表 1 分組列出了所有內(nèi)置 Tcl 命令。除了已經(jīng)提及的命令,Tcl 還提供了操縱字符串的命令(比較、匹配
和類(lèi)似 printf/scanf 的操作),操縱文件和文件名字的命令,和 fork 子進(jìn)程并返回子進(jìn)程的標(biāo)準(zhǔn)輸出作為
結(jié)果的命令。內(nèi)置 Tcl 命令提供了簡(jiǎn)單但完整的編程環(huán)境??梢园慈N方式擴(kuò)展內(nèi)置設(shè)施:寫(xiě) tclproc;把
其他程序作為子進(jìn)程調(diào)用;或按下一節(jié)描述的那樣用 C 過(guò)程定義新命令。
3. 在應(yīng)用中嵌入 Tcl
盡管內(nèi)置 Tcl 命令可以令人信服的用作獨(dú)立的編程系統(tǒng),Tcl 實(shí)際上意圖被嵌入到應(yīng)用程序中。我已經(jīng)建造
了使用 Tcl 的幾個(gè)應(yīng)用程序,其中之一是針對(duì) X 的叫做 mx 的一個(gè)基于鼠標(biāo)的編輯器。在本文的余下部分,
我將使用來(lái)自 mx 的例子來(lái)展示 Tcl 如何與包圍它的應(yīng)用進(jìn)行交互。
使用 Tcl 的應(yīng)用程序用同特定應(yīng)用有關(guān)的一些額外的命令來(lái)擴(kuò)展內(nèi)置命令。例如,時(shí)鐘程序可以提供額外的
命令來(lái)控制時(shí)鐘如何顯示和設(shè)置鬧鐘;mx 編輯器提供額外的命令來(lái)從磁盤(pán)讀取文件,在窗口中顯示它,
選擇和修改一定范圍內(nèi)的字節(jié),和把修改后的文件寫(xiě)回磁盤(pán)。應(yīng)用程序員只需要寫(xiě)特定于應(yīng)用的命令;內(nèi)置
命令“免費(fèi)的”提供編程能力和擴(kuò)展能力。對(duì)于用戶(hù),特定于應(yīng)用的命令表現(xiàn)的如同內(nèi)置命令一樣。
圖表 2. Tcl 庫(kù)為 Tcl 語(yǔ)言提供一個(gè)分析器、一組內(nèi)置命令、和一些實(shí)用工具過(guò)程。應(yīng)用提供特定于應(yīng)用的命令加上收集要執(zhí)行的命令的過(guò)程。命令由 Tcl 分析,并接著傳遞給相關(guān)的(在 Tcl 中或者在應(yīng)用中)命令過(guò)程去執(zhí)行。
圖表 2 展示了在 Tcl 和應(yīng)用的余下部分之間的聯(lián)系。Tcl 是連接到應(yīng)用上的一個(gè) C 庫(kù)包。Tcl 庫(kù)包含針對(duì)
Tcl 語(yǔ)言的一個(gè)分析器、執(zhí)行內(nèi)置命令的過(guò)程、和做表達(dá)式求值和列表管理這種事情的一組實(shí)用工具過(guò)程。
分析器包括可以用來(lái)擴(kuò)展語(yǔ)言的命令集的一個(gè)擴(kuò)展接口。
要使用 Tcl,應(yīng)用首先要使用下面的庫(kù)過(guò)程建立叫 interpreter 的一個(gè)對(duì)象:
Tcl_Interp * Tcl_CreateInterp()
解釋器由一組命令、一組變量綁定和一個(gè)命令執(zhí)行狀態(tài)組成。它是多數(shù) Tcl 庫(kù)過(guò)程操縱的基本單位。簡(jiǎn)單
應(yīng)用將只使用一個(gè)單一的解釋器,更復(fù)雜的應(yīng)用可以為不同用途而使用多個(gè)解釋器。例如,mx 為在屏幕
上的每個(gè)窗口使用一個(gè)解釋器。
一旦應(yīng)用建立了一個(gè)解釋器,它就可以調(diào)用 Tcl_CreateCommand 過(guò)程來(lái)用特定于命令的過(guò)程來(lái)擴(kuò)展這個(gè)
解釋器:
typedef int (*Tcl_CmdProc)(ClientData clientData,
Tcl_Interp *interp, int argc, char *argv[]);
Tcl_CreateCommand(Tcl_Interp *interp, char *name,
Tcl_CmdProc proc, ClientData clientData)
每次對(duì) Tcl_CreateCommand 的調(diào)用都把一個(gè)特定的命令名字(name)、同一個(gè)實(shí)現(xiàn)這個(gè)命令的過(guò)程(proc)、
和一個(gè)任意的傳遞到這個(gè)過(guò)程的一個(gè)單字值(clientData)關(guān)聯(lián)起來(lái)。
在建立了特定于應(yīng)用的命令之后,應(yīng)用進(jìn)入一個(gè)主循環(huán),收集命令并把它們傳遞給 Tcl_Eval 過(guò)程去執(zhí)行:
int Tcl_Eval(Tcl_Interp *interp, char *cmd)
在最簡(jiǎn)單的形式中,應(yīng)用可以簡(jiǎn)單的從終端或屏幕讀取命令。在 mx 編輯器中為事件如擊鍵、鼠標(biāo)按鈕或
菜單激活都關(guān)聯(lián)上 Tcl 命令;每次事件發(fā)生的時(shí)候,就把對(duì)應(yīng)的 Tcl 命令傳遞給 Tcl_Eval。
Tcl_Eval 過(guò)程把它的 cmd 參數(shù)分析成字段,在與這個(gè)解釋器相關(guān)聯(lián)的表格中查找命令的名字,并調(diào)用與
這個(gè)命令相關(guān)聯(lián)的命令過(guò)程。所有的命令過(guò)程,不管內(nèi)置的還是特定于應(yīng)用的,都按照上面 Tcl_CmdProc
中 typedef 描述的方式,以同樣的方式來(lái)調(diào)用。向命令過(guò)程傳遞描述命令參數(shù)的一個(gè)字符串的數(shù)組(argc 和
argv),加上在建立的時(shí)候關(guān)聯(lián)到命令上的 clientData 值。ClientData 典型的是到包含執(zhí)行這個(gè)命令所需
信息的特定于應(yīng)用的結(jié)構(gòu)一個(gè)指針。例如,在 mx 中 clientData 參數(shù)指向一個(gè)每窗口數(shù)據(jù)結(jié)構(gòu),描述了編輯
的文件和在其中顯示的窗口。
控制機(jī)制如 if 和 for 是使用對(duì) Tcl_Eval 的遞歸調(diào)用實(shí)現(xiàn)的。例如,if 命令的命令過(guò)程把它的第一個(gè)參數(shù)作為
表達(dá)式求值;如果結(jié)果是非零,則它遞歸的調(diào)用 Tcl_Eval 來(lái)把它的第二個(gè)參數(shù)作為 Tcl 命令來(lái)執(zhí)行。在這個(gè)
命令執(zhí)行期間,可以再次遞歸調(diào)用 Tcl_Eval,以此類(lèi)推。Tcl_Eval 還遞歸的調(diào)用自身來(lái)執(zhí)行出現(xiàn)在參數(shù)中的
方括號(hào)包圍的命令。
甚至 tclproc 如 fac 都使用了同樣的基本機(jī)制。在調(diào)用了 proc 命令建立 fac 的時(shí)候,proc 命令過(guò)程通過(guò)調(diào)用
Tcl_CreateCommand 建立一個(gè)新命令,這在圖表 3 中展示。新命令擁有名字 fac。它的命令過(guò)程 (對(duì)
Tcl_CreateCommand 調(diào)用中的 proc)是叫做 InterpProc 的一個(gè)特殊的 Tcl 庫(kù)過(guò)程,而它的 clientData 是到
描述這個(gè) tclproc 的結(jié)構(gòu)的一個(gè)指針。這個(gè)結(jié)構(gòu)包含了,同其他東西在一起的,這個(gè) tclproc 的過(guò)程體的一個(gè)
復(fù)件(給 proc 命令的第三個(gè)參數(shù))。在調(diào)用 fac 命令的時(shí)候,Tcl_Eval 調(diào)用 InterpProc,它依次調(diào)用
Tcl_Eval 來(lái)執(zhí)行 tclproc 的過(guò)程體。需要有一些額外的代碼來(lái)把 fac 命令的參數(shù)(它們?cè)趥鬟f給 InterpProc
的 argv 數(shù)組中)關(guān)聯(lián)到在 fac 過(guò)程體內(nèi)使用的 x 變量上,和支持帶有局部作用域的變量,但是用于 tclprocs
的機(jī)制多數(shù)與用于任何其他 Tcl 命令的機(jī)制相同。
圖表 3. tclproc (用 Tcl 寫(xiě)的過(guò)程)的建立和執(zhí)行: (a) 調(diào)用了 proc 命令,就是說(shuō),要建立 fac 過(guò)程;(b) Tcl 分析器調(diào)用與 proc 相關(guān)聯(lián)的命令過(guò)程;(c) proc 命令過(guò)程建立一個(gè)數(shù)據(jù)結(jié)構(gòu)來(lái)持有是 fac 過(guò)程體的 Tcl 命令;(d) fac 注冊(cè)為一個(gè)新的 Tcl 命令,帶有 InterpProc 作為它的命令過(guò)程;(e) fac 作為 Tcl 命令而被調(diào)用;(f) Tcl 分析器把 InterpProc 作為 fac 的命令過(guò)程來(lái)調(diào)用;(g) InterpProc 從數(shù)據(jù)結(jié)構(gòu)中取回 fac 的過(guò)程體;(h) 把在 fac 過(guò)程體中的 Tcl 命令傳遞回到 Tcl 分析器去執(zhí)行。
Tcl 命令過(guò)程向 Tcl_Eval 返回兩個(gè)結(jié)果: 一個(gè)整數(shù)返回代碼和一個(gè)字符串。返回代碼是作為過(guò)程的結(jié)果返回
的,而這個(gè)字符串存儲(chǔ)在解釋器中,以后可以從中取回它。Tcl_Eval 向它的調(diào)用者返回相同的代碼和字符串
。表格 I 總結(jié)了返回代碼和字符串。正常的返回代碼是 TCL_OK 和包含命令結(jié)果的字符串。如果 在執(zhí)行
命令中發(fā)生一個(gè)錯(cuò)誤,則返回代碼將是 TCL_ERROR 而字符串將描述錯(cuò)誤狀況。在返回的 TCL_ERROR
的時(shí)候(或者任何不是 TCL_OK 的值),對(duì)于嵌套命令的通常的動(dòng)作是向它們的調(diào)用者返回相同的代碼和
字符串,回退(unwind)所有未決的命令執(zhí)行,直到返回代碼和字符串最終從對(duì) Tcl_Eval 的頂層調(diào)用返回。
在這個(gè)時(shí)刻應(yīng)用通常向用戶(hù)顯示錯(cuò)誤消息,通常在終端上打印它或在一個(gè)通知窗口中顯示它。
返回代碼 意義 字符串
TCL_OK 命令正常完成 結(jié)果
TCL_ERROR 在命令中出現(xiàn)了錯(cuò)誤 錯(cuò)誤消息
TCL_BREAK 應(yīng)當(dāng)從最內(nèi)層循環(huán)中退出 沒(méi)有
TCL_CONTINUE 應(yīng)當(dāng)跳過(guò)最內(nèi)層迭代 沒(méi)有
TCL_RETURN 應(yīng)當(dāng)從最內(nèi)層過(guò)程中返回 過(guò)程結(jié)果
表格 I. 每個(gè) Tcl 命令都返回描述發(fā)生了什么的一個(gè)代碼和提供補(bǔ)充信息的一個(gè)字符串。如果返回代碼不是 TCL_OK,則回退(unwind)嵌套的命令并返回相同的代碼,直到達(dá)到頂層或預(yù)備來(lái)處理異常返回代碼的某個(gè)命令。
不是 TCL_OK 或 TCL_ERROR 的返回代碼導(dǎo)致部分回退。例如,break 命令返回一個(gè) TCL_BREAK 代碼。
它導(dǎo)致回退嵌套的命令執(zhí)行,直到達(dá)到一個(gè)嵌套的 for 或 foreach 命令。在 for 或 foreach 命令遞歸的調(diào)用
Tcl_Eval 的時(shí)候,它特別的檢查 TCL_BREAK 結(jié)果。當(dāng)這個(gè)代碼出現(xiàn)的時(shí)候,for 或 foreach 命令終止這個(gè)
循環(huán),但是它不向它的調(diào)用者返回 TCL_BREAK。它轉(zhuǎn)而返回 TCL_OK。這樣就不會(huì)有更高層次的執(zhí)行被
中止(abort)。TCL_CONTINUE 返回代碼也由 for 和 foreach 命令處理(它們繼續(xù)做下一個(gè)循環(huán)迭代),而
TCL_RETURN 由 InterpProc 過(guò)程處理。只有一些命令過(guò)程,如 break 和 for,知道關(guān)于特殊返回代碼如
TCL_BREAK 的事情;其他命令過(guò)程在見(jiàn)到不是 TCL_OK 的返回代碼的時(shí)候就是簡(jiǎn)單的中止。
可以使用 catch 命令來(lái)防止對(duì) TCL_ERROR 返回的完全回退。catch 接受是要執(zhí)行的 Tcl 命令的一個(gè)參數(shù)。
它把這個(gè)命令傳遞到 Tcl_Eval 去執(zhí)行,但總是返回 TCL_OK。如果在這個(gè)命令中發(fā)生一個(gè)錯(cuò)誤,catch 的
命令過(guò)程檢測(cè)來(lái)自 Tcl_Eval 的 TCL_ERROR 返回值,在 Tcl 變量中保存有關(guān)錯(cuò)誤的信息,并接著向它的
調(diào)用者返回 TCL_OK。在幾乎所有的情況下,我認(rèn)為對(duì)一個(gè)錯(cuò)誤最好的響應(yīng)就是退出所有的命令調(diào)用并
通知用戶(hù);catch 是為那些少見(jiàn)的場(chǎng)合提供的,這里期望著一個(gè)錯(cuò)誤并做出處理而不用中止。
4. Tcl 和窗口應(yīng)用
可嵌入的命令語(yǔ)言如 Tcl 在窗口環(huán)境中提供了特別的好處。部分原因是在窗口環(huán)境中有很多交互式程序(所以
有很多地方要使用命令語(yǔ)言),部分的原因是在今天的窗口環(huán)境中可配置性是重要的,并且語(yǔ)言如 Tcl 提供了
做重新配置的靈活性。Tcl 在窗口應(yīng)用中可以用于兩個(gè)目的: 配置應(yīng)用的界面動(dòng)作,配置應(yīng)用的界面外觀(guān)。
在下面的段落中討論這兩個(gè)用途。
Tcl 的第一個(gè)用法是用于界面動(dòng)作。理想的,對(duì)應(yīng)用重要的每個(gè)事件都應(yīng)當(dāng)綁定上 Tcl 命令。每次擊鍵、
每次鼠標(biāo)移動(dòng)或鼠標(biāo)按鈕按下(或釋放)、和每個(gè)菜單條目都應(yīng)當(dāng)關(guān)聯(lián)上 Tcl 命令。
當(dāng)事件發(fā)生時(shí),首先把它映射到它的 Tcl 命令上,接著通過(guò)把這個(gè)命令傳遞到 Tcl_Eval 來(lái)執(zhí)行它。應(yīng)用
不應(yīng)當(dāng)直接接收任何動(dòng)作;所有動(dòng)作都應(yīng)當(dāng)首先通過(guò) Tcl 來(lái)傳遞。進(jìn)一步,應(yīng)用應(yīng)當(dāng)提供 Tcl 命令允許
用戶(hù)改變與任何事件相關(guān)聯(lián)的 Tcl 命令。
在交互式的窗口應(yīng)用中,Tcl 的使用可能對(duì)于初級(jí)用戶(hù)是不可見(jiàn)的: 他們將使用按鈕、菜單和其他界面構(gòu)件
來(lái)操縱應(yīng)用。但是,如果使用 Tcl 作為所有界面動(dòng)作的中間媒介,則會(huì)產(chǎn)生兩個(gè)好處。首先,使得寫(xiě) Tcl
程序來(lái)重新配置界面成為可能。例如,用戶(hù)將能夠重新綁定擊鍵、改變鼠標(biāo)按鈕、或把一個(gè)現(xiàn)存的操作
替代為指定為一組 Tcl 命令或 tclproc 的更加復(fù)雜的操作。第二個(gè)好處是這種方式強(qiáng)制所有的應(yīng)用的功能都
可通過(guò) Tcl 來(lái)訪(fǎng)問(wèn): 任何可以使用鼠標(biāo)或鍵盤(pán)調(diào)用的東西都可以使用 Tcl 程序調(diào)用。這使得有可能寫(xiě)模擬
程序動(dòng)作的 tclproc,或把程序的基本動(dòng)作組合到更加強(qiáng)力的動(dòng)作中。這還允許交互式會(huì)話(huà)作為一序列 Tcl
命令而被記錄和重演(參見(jiàn)章節(jié) 5)。
在窗口應(yīng)用中 Tcl 的第二個(gè)用法是配置應(yīng)用的外觀(guān)。所有應(yīng)用的界面構(gòu)件(X 術(shù)語(yǔ)是“組件-widgets”),比如
標(biāo)簽、按鈕、文本錄入框、菜單和滾動(dòng)條應(yīng)當(dāng)可以使用 Tcl 命令來(lái)配置。例如,在按鈕的情況下,應(yīng)用(或
按鈕組件代碼)應(yīng)當(dāng)提供 Tcl 命令來(lái)改變按鈕的大小和位置、它的文本、它的顏色、和動(dòng)作(當(dāng)然是一個(gè) Tcl
命令),在這個(gè)按鈕活躍的時(shí)候調(diào)用。這使得有可能讓用戶(hù)寫(xiě) Tcl 程序來(lái)個(gè)人化他們所使用的應(yīng)用的格局和
外觀(guān)。這種重新配置能力的最常見(jiàn)使用、可能就是用在程序開(kāi)始執(zhí)行時(shí)自動(dòng)讀取的 Tcl 命令文件中。但是,
也可以用 Tcl 命令在應(yīng)用運(yùn)行的時(shí)候改變它的外觀(guān),如果能證明有用的話(huà)。
如果按上面描述的那樣使用 Tcl,則它將充當(dāng)一種用戶(hù)界面的說(shuō)明語(yǔ)言??梢詫?xiě)用戶(hù)界面編輯器來(lái)顯示組件,
并讓用戶(hù)重新安排它們并配置屬性,比如顏色和相關(guān)聯(lián)的 Tcl 命令。界面編輯器可以接著把關(guān)于界面的信息
輸出為 Tcl 命令文件,在應(yīng)用啟動(dòng)的時(shí)候讀取。一些當(dāng)前的界面編輯器輸出 C 代碼,需要接著編譯到應(yīng)用中
[7];不幸的是,這種方式要求重新編譯一個(gè)應(yīng)用來(lái)改變它的界面(或者作為可供選擇的一種方式,要求動(dòng)態(tài)
代碼裝載設(shè)施)。如果把 Tcl 用作界面說(shuō)明語(yǔ)言,則不需要重新編譯,而且一個(gè)簡(jiǎn)單的應(yīng)用二進(jìn)制程序可以
支持多種不同的界面。
5. 應(yīng)用間通信
如果在一個(gè)環(huán)境中的所有工具都基于相同的可嵌入命令語(yǔ)言如 Tcl,則好處就更大的。首先,用戶(hù)只需要
學(xué)習(xí)一門(mén)基本的命令語(yǔ)言;要從一個(gè)應(yīng)用移動(dòng)到另一個(gè)只需要為這個(gè)新應(yīng)用學(xué)習(xí)(很少的?)特定于應(yīng)用的
命令。其次,通用的界面編輯器成為可能,如前面章節(jié)描述的那樣。第三,按我的觀(guān)點(diǎn)最重要的是,Tcl
可以提供在應(yīng)用之間通信的一種方式。
我已經(jīng)用叫做 send 的一個(gè)額外的 Tcl 命令、為 X11 實(shí)現(xiàn)了一種通信機(jī)制。為了讓 send 工作,與 X11
應(yīng)用相關(guān)聯(lián)的每個(gè) Tcl 解釋器都要給出一個(gè)文本的名字,比如稱(chēng)呼 X 郵件處理器為 xmh,稱(chēng)呼 mx 在其中
顯示叫做 foo.c 文件的那個(gè)窗口為 mx.foo.c。send 命令接受兩個(gè)參數(shù): 解釋器的名字和要在這個(gè)解釋器中
執(zhí)行的 Tcl 命令。send 安排把這個(gè)命令傳遞到包含指名解釋器的進(jìn)程;命令由那個(gè)解釋器執(zhí)行并把結(jié)果
(返回代碼和字符串)返回給發(fā)起 send 命令的應(yīng)用。
send 的 X11 實(shí)現(xiàn)使用了與根窗口連結(jié)的一個(gè)特殊屬性。這個(gè)屬性存儲(chǔ)所有解釋器的命令加上給每個(gè)解釋器
的窗口標(biāo)識(shí)符。通過(guò)把命令添加到在解釋器相關(guān)聯(lián)的窗口中的特定屬性上來(lái)發(fā)送它。擁有這個(gè)解釋器的進(jìn)程
檢測(cè)到這個(gè)屬性的變更。它讀取這個(gè)屬性,執(zhí)行命令,并把結(jié)果信息添加到與發(fā)送應(yīng)用相關(guān)聯(lián)的屬性上。
最后,發(fā)送應(yīng)用檢測(cè)到這個(gè)屬性的變更,讀取結(jié)果信息,并把它返回為 send 命令的結(jié)果。
send 命令為一個(gè)應(yīng)用控制另一個(gè)應(yīng)用提供了一種強(qiáng)力方式。例如,調(diào)試器在單步跟蹤一個(gè)程序的時(shí)候可以
發(fā)送命令到編輯器來(lái)高亮當(dāng)前源代碼行。還有,用戶(hù)界面編輯器可以使用 send 來(lái)直接操縱一個(gè)應(yīng)用的窗口:
不用修改界面編輯器顯示的應(yīng)用界面的偽裝(dummy)版本,界面編輯器可以使用 send 來(lái)修改一個(gè)“活著的”
應(yīng)用的界面,此時(shí)還能保存配置到配置文件中。這將允許界面設(shè)計(jì)者試驗(yàn)新界面的觀(guān)感并對(duì)界面做出改變
逐步增加上去。
使用 send 的另一個(gè)例子是改變用戶(hù)偏好。如果一個(gè)用戶(hù)來(lái)到了已經(jīng)為其他用戶(hù)配置好的顯示器面前,這個(gè)
新用戶(hù)可以運(yùn)行一個(gè)程序來(lái)找出幾乎所有在屏幕上現(xiàn)存的應(yīng)用程序(通過(guò)查詢(xún)包含它們名字的屬性),對(duì)每個(gè)
應(yīng)用讀取這個(gè)新用戶(hù)的配置文件,并向這些應(yīng)用發(fā)送命令來(lái)按這個(gè)新用戶(hù)的偏好來(lái)重新配置它們。當(dāng)老用戶(hù)
回來(lái)的時(shí)候,他可以調(diào)用同一個(gè)程序恢復(fù)最初的偏好。
send 還可以用來(lái)記錄涉及多個(gè)應(yīng)用的交互式會(huì)話(huà),并在以后重演這個(gè)會(huì)話(huà)(就是說(shuō),用于演示目的)。這需要
叫做 trace 的一個(gè)額外的 Tcl 命令;trace 將接受一個(gè)單一的參數(shù)(一個(gè) Tcl 命令字符串),并導(dǎo)致在這個(gè)解釋
器中在每個(gè)其他命令執(zhí)行之前執(zhí)行這個(gè)命令字符串。在一個(gè)單一的應(yīng)用中,將使用 trace 在每個(gè) Tcl 命令
執(zhí)行之前記錄它,這樣這些命令就可以在以后重演。在多應(yīng)用環(huán)境中,可是使用 send 建造記錄器程序。
記錄器發(fā)送 trace 命令到需要記錄的每個(gè)應(yīng)用。trace 命令安排把同在這個(gè)應(yīng)用中執(zhí)行的每個(gè)命令有關(guān)的
信息發(fā)送回到記錄器。記錄器接著把關(guān)于哪個(gè)應(yīng)用執(zhí)行了哪個(gè)命令的信息記入日志。記錄器可以把命令再次
發(fā)送回到那個(gè)應(yīng)用來(lái)重新執(zhí)行它們。trace 命令在 Tcl 還不存在,但它是很容易增加的。
send 為進(jìn)程間通信提供了比今天能獲得的機(jī)制更加強(qiáng)力的機(jī)制。今天的應(yīng)用能用到的唯一易用的通信形式
是選擇或剪切緩沖區(qū): 它是一個(gè)單一的字符串,可以由一個(gè)應(yīng)用設(shè)置而由另一個(gè)應(yīng)用讀取。send 提供了類(lèi)似
于遠(yuǎn)程過(guò)程調(diào)用[3]的一種更一般的通信形式,如果所有應(yīng)用的功能都可以通過(guò) Tcl 來(lái)獲得,如在第 4 節(jié)描述
的那樣,則 send 能讓每個(gè)應(yīng)用的功能都對(duì)其他應(yīng)用也是可能獲得的。
如果 Tcl (和 send)在窗口應(yīng)用中得到廣泛使用,我相信會(huì)出現(xiàn)一種更好的交互環(huán)境,它是由大量小而專(zhuān)門(mén)的
應(yīng)用而不是一些單體(monolithic)應(yīng)用組成。今天的應(yīng)用不能很好的相互通信,所以每個(gè)應(yīng)用都必須結(jié)合它
需要的所有功能。例如,一些基于窗口的調(diào)試器包含了內(nèi)置的文本編輯器,這樣他們才可以高亮當(dāng)前的執(zhí)行
點(diǎn)。使用了 Tcl 和 send,調(diào)試器和編輯器就可以是單獨(dú)的程序,在需要的時(shí)候相互發(fā)送命令。理想的, 可以
用以一種令人激動(dòng)的新方式一起工作的大量小應(yīng)用替代單體應(yīng)用,就象 UNIX shell 允許把大量小的文本處理
應(yīng)用組合在一起。我認(rèn)為 Tcl,或類(lèi)似它的某種其他語(yǔ)言,將提供把 1990 年代的窗口應(yīng)用綁定在一起的膠水。
6. 狀態(tài)和性能
Tcl 語(yǔ)言是在 1987 年秋天設(shè)計(jì)并在 1988 年冬天實(shí)現(xiàn)的。在 1988 年春天我把 Tcl 結(jié)合到 mx 編輯器中(它
已經(jīng)存在了,但是帶有低級(jí)的命令語(yǔ)言),還結(jié)合到叫 Tx 的一個(gè)作為同伴的終端模擬器中。在這一年半中,
這些程序都已經(jīng)在 Berkeley 的一個(gè)小型用戶(hù)社區(qū)中使用了。上面描述的所有的 Tcl 語(yǔ)言設(shè)施都是存在的,
除了 send 命令仍是原型形式和 trace 仍未實(shí)現(xiàn)之外。在第 4 節(jié)中描述的某些特征,比如菜單和擊鍵綁定在
mx 中實(shí)現(xiàn)了,但是以一種特別的樣式: Tcl 仍未與組件集相整合。我正在建造一個(gè)新的工具箱、和完全基于
Tcl 的組件集。當(dāng)它完成的時(shí)候,我希望它能提供在第 4 節(jié)描述的所有特征。在本文寫(xiě)作的時(shí)候,實(shí)現(xiàn)才
剛剛起步。
Tcl 命令 Sun-3 時(shí)間 (微秒) DS3100 時(shí)間(微秒)
set a 1 225 57
list abc def ghi jkl 460 138
if {4 > 3} {set a 1} 700 220
proc fac x {
if { $x == 1} {return 1}
return [expr {$x*[fac [expr $x-1]]}]
} 1280 380
fac 5 11250 3630
表格 II. 各種 Tcl 命令的花費(fèi),在 Sun-3/75 工作站和 DECstation3100 上進(jìn)行的測(cè)量。命令 fac 5 執(zhí)行了總計(jì) 23 個(gè) Tcl 命令,平均命令時(shí)間大約是在 Sun-3 上 500 微秒在 DECstation3100 上 160 微秒。
表格 II 展示了 Tcl 在兩種不同的工作站上執(zhí)行各種命令花費(fèi)的時(shí)間。在 Sun-3 工作站上,簡(jiǎn)單命令的平均
時(shí)間是大約 500 微秒,而在 DECstation 3100 上命令的平均時(shí)間是大約 160 微秒。盡管 mx 目前不對(duì)每次
鼠標(biāo)移動(dòng)都使用一個(gè) Tcl 命令,在表格 II 中的時(shí)間表明了,即使是在 Sun-3 工作站上,沒(méi)有響應(yīng)的明顯減低
是可能的。例如,如果鼠標(biāo)移動(dòng)事件每秒發(fā)生 100 次,Tcl 為每個(gè)事件分派一個(gè)命令的花費(fèi)將只消耗 Sun-3
處理器的 1-2%。在目前使用 Tcl 的方式下(擊鍵和菜單綁定由一些命令組成),沒(méi)有明顯與 Tcl 有關(guān)的延遲,
對(duì)于特定于應(yīng)用的命令比如 mx 編輯器的那些命令,執(zhí)行這些命令的時(shí)間比 Tcl 分析它并調(diào)用命令過(guò)程需要
的時(shí)間要大很多。
Tcl 庫(kù)足夠小以便用在各種程序中,甚至是沒(méi)有共享庫(kù)機(jī)制的系統(tǒng)上。Tcl 代碼由大約 7000 行 C 代碼組成
(其中一半是注釋)。在 Motorola 68000 上編譯的時(shí)候,它生成大約 27000 字節(jié)的目標(biāo)代碼。
7. 比較
Tcl 語(yǔ)言在表面上相當(dāng)類(lèi)似于 Lisp,除了 Tcl 使用花括號(hào)或方括號(hào)替代了圓括號(hào),和在命令的最外層不需要
包圍圓括號(hào)之外。在 Tcl 和 Lisp 之間最大的區(qū)別是 Lisp 缺省的求值參數(shù),而在 Tcl 中參數(shù)不被求值除非
包圍著方括號(hào)。這意味著在 Tcl 中如果一個(gè)參數(shù)需要被求值則需要做更多的鍵入努力,而在 Lisp 中如果一個(gè)
參數(shù)要被引用(不被求值)則需要做更多的鍵入努力。就我而言對(duì)于命令語(yǔ)言不求值通常是更需要的結(jié)果,所以
我在 Tcl 中做了這種缺省。Tcl 還有比 Lisp 更少的數(shù)據(jù)類(lèi)型;這么做是為了簡(jiǎn)化 Tcl 庫(kù)和圍繞它的 C 應(yīng)用
之間的接口。
在提供可以用來(lái)控制很多不同的應(yīng)用程序的一個(gè)框架方面,Emacs 編輯器類(lèi)似于 Tcl。例如,子進(jìn)程可以在
Emacs 窗口中運(yùn)行,并且用戶(hù)可以寫(xiě) Emacs 命令腳本來(lái) (a) 生成輸入到應(yīng)用的命令序列和 (b) 重新格式化
應(yīng)用的輸出。這允許用戶(hù)去修飾應(yīng)用的基本設(shè)施,編輯它們的輸出,諸如此類(lèi)。在 Emacs 和 Tcl 之間的
不同是編程能力集中在 Emacs 中:應(yīng)用不能相互交流除非 Emacs 充當(dāng)中間媒介(就是說(shuō)在兩個(gè)應(yīng)用之間
架設(shè)通信機(jī)制,要在應(yīng)用之間來(lái)回傳遞信息、代碼必須寫(xiě)在 Emacs 中)。Tcl 的方式是分散的:每個(gè)應(yīng)用
都有它自己的命令解釋器并直接相互通信。
最后,比較 Tcl 和 NeWS [9] 是很有趣的,它是基于 Postscript 語(yǔ)言的一個(gè)窗口系統(tǒng)。NeWS 允許應(yīng)用下載
Postscript 程序到窗口服務(wù)器中來(lái)改變用戶(hù)界面和修改系統(tǒng)的其他方面。在某種意義上,這類(lèi)似于 Tcl 中的
send 命令,在這種系統(tǒng)中,應(yīng)用可以把程序發(fā)送到服務(wù)器上面去執(zhí)行。但是,NeWS 的機(jī)制比 Tcl 更少
一般性:NeWS 應(yīng)用生成 Postscript 程序作為輸出,但是它們不是必須響應(yīng)作為輸入的 Postscript 程序。
換句話(huà)說(shuō),NeWS 應(yīng)用可以通過(guò)控制服務(wù)器來(lái)影響其他應(yīng)用的界面,但是它們不能像在 Tcl 中那樣,直接
的調(diào)用其他應(yīng)用的特定于應(yīng)用的操作。
作為總結(jié),Tcl 方式比 Emacs 或 NeWS 方式更少集中性。對(duì)于有著大量獨(dú)立的工具的窗口環(huán)境,我認(rèn)為
分散的方式更有意義。出于對(duì) Emacs 的公平,指出 Emacs 不是為這種環(huán)境而設(shè)計(jì)是很重要的,Emacs
在它設(shè)計(jì)用于的環(huán)境中工作的非常令人滿(mǎn)意(ASCII 終端和批處理方式的應(yīng)用)。值得一提的還有應(yīng)用之間
的直接通信不是 NeWS 系統(tǒng)設(shè)計(jì)明確的目標(biāo)。
8. 結(jié)論
我認(rèn)為 Tcl 能以三種一般的方式來(lái)改善我們的交互環(huán)境。首先,Tcl 可以用來(lái)通過(guò)向單獨(dú)的工具提供可編程
的命令解釋器來(lái)增進(jìn)它們;這允許用戶(hù)去定制工具和擴(kuò)展它們的功能。其次,Tcl 可以提供跨越各類(lèi)工具的
一個(gè)統(tǒng)一的命令語(yǔ)言;這使它便利了用戶(hù)編程這些工具,并允許建造獨(dú)立于工具的設(shè)施,比如界面編輯器。
第三,Tcl 為工具相互控制提供一種機(jī)制;這鼓勵(lì)了為窗口應(yīng)用提供一種更模塊化的方式,并使以新方式
重新使用舊應(yīng)用成為可能。按照我的觀(guān)點(diǎn)第三個(gè)好處是潛在的最重要的。
迄今為止我對(duì) Tcl 經(jīng)驗(yàn)是積極而有限的。在被徹底的評(píng)估之前,Tcl 需要更大的用戶(hù)社區(qū)和更完全的整合到
一個(gè)窗口工具箱中。Tcl 庫(kù)的源代碼目前對(duì)于公眾是免費(fèi)的、不授加許可的形式,我希望不久就能生產(chǎn)出
基于 Tcl 的工具箱。
9. 致謝
Sprite 計(jì)劃的成員為基于 Tcl 的編輯器和終端模擬器充當(dāng)了廉價(jià)勞工;沒(méi)有他們的幫助這門(mén)語(yǔ)言是不能發(fā)展
到今天的狀態(tài)的。Fred Douglis、John Hartman、Ken Shirriff 和 Brent Welch 提供了有益的評(píng)論來(lái)增進(jìn)
本文的表述。
10. 引用
[1] Abelson, H. and Sussman, G.J. Structure and Interpretation of Computer Programs, MIT Press, Cambridge, MA, 1985.
[2] Adobe Systems, Inc. Postscript Language Tutorial and Cookbook, Addison-Wesley, Reading, MA, 1985.
[3] Birrell, A. and Nelson, B. ‘‘Implementing Remote Procedure Calls.’’ ACM Transactions on Computer Systems, Vol. 2, No. 1, February 1986, pp. 39-59.
[4] Brodie, L. Starting FORTH: An Introduction to the FORTH Language and Operating System for Beginners and Professionals, Prentice Hall, Englewood Cliffs, NJ, 1981.
[5] Kernighan, B.W. and Pike, R. The UNIX Programming Environment, Prentice Hall, Englewood Cliffs, NJ, 1984.
[6] Kernighan, B.W. and Ritchie, D.M. The C Programming Language, Second Edition, Prentice Hall, Englewood Cliffs, NJ, 1988.
[7] Mackey, K., Downs, M., Duffy, J., and Leege, J. ‘‘An Interactive Interface Builder for Use with Ada Programs,’’ Xhibition Conference Proceedings, 1989.
[8] Stallman, R. GNU Emacs Manual, Fourth Edition, Version 17, February 1986.
[9] Sun Microsystems, Inc. NeWS Technical Overview, Sun Microsystems, Inc. PN 800-1498-05, 1987.
本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
初識(shí) Shell腳本 - 語(yǔ)法
一文學(xué)完Linux Shell編程(強(qiáng)烈建議收藏)
Tcl / Tk 大全
幾個(gè)免費(fèi)的Scheme(Lisp)解釋器
Tcl簡(jiǎn)介(一)
作為程序員,你有過(guò)一個(gè)簡(jiǎn)單 bug 查詢(xún)了很久才解決的經(jīng)歷嗎?
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服