Történeti lista
Amikor olyan alkalmazással dolgozunk, amelynek vezérlése részben vagy egészben parancsokkal történik, gyakran fordul elő, hogy korábban kiadott parancsokat szertnént megismételni, esetleg kisebb változtatással. Az alkalmazást akkor érezzük igazán kényelmesnek, ha nyújt olyan lehetőségeket, amelyek révén elkerülhetjük a parancs sokadszori begépelését. A Tcl-ben írt és Tcl parancsokat fogadó programokat a history parancs ruházza fel a kívánt lehetőséggel.
history ?művelet? ?arg ...?
A history parancs lehetővé teszi, hogy egy történeti listában tartsuk nyilván az utoljára kiadott egynéhány parancsot, és hogy ezekre hivatkozhassunk. A hivatkozás három formában történhet:
  • A parancs sorszámával. A parancsok rendelkeznek egy egytől kezdődő sorszámmal; egy pozitív szám a megfelelő sorszámú parancsot jelenti.
  • A parancs relatív sorszámával. Negatív számmal a történeti lista végéhez relatívan adhatunk meg parancsot (-1 az utolsó, -2 az utolsó előtti parancsot jelenti).
  • Egy mintával. A minta a arra a legutóbb kiadott parancsra hivatkozik, amelynek a prefixét képezi, vagy amelyre a string match parancs szerint illeszkedik.

Közönséges történeti parancsok

Ebbe a kategóriába azok a parancsok tartoznak, amelyeknek nincsen közvetlen szerepe a történeti listában rögzített parancsok ismételt kiadásában.
history keep méret
Ezzel a paranccsal adhatjuk meg, hogy a történeti lista hány parancsot őrizzen meg. Alapértelmezésben a történeti lista 20 parancsot tud tárolni. A parancs üres stringet ad vissza.
history add parancs ?exec?
A megadott parancsot felveszi a történeti lista végére. Ha az utolsó argumentum exec vagy ennek prefixe, parancs végrehajtódik, és visszatérési értéke lesz a history add parancs visszatérési értéke is. Különben üres stringet kapunk vissza.
history change új ?hivatkozás?
A hivatkozott (alapértelmezésben az utolsó) parancsot lecseréli az új parancsra.
history nextid
Azt a sorszámot adja vissza, amelyet a következőként a történeti listába kerülő parancs fog kapni. Ezt a számot a parancsokat fogadó alkalmazás például kiírhatja a parancs bekérése előtt.
history ?info? ?szám?
Visszaad egy stringet, amely ember által olvasható formában tartalmazza a történeti listát (soronként egy-egy parancs sorszámát és magát a parancsot). A szám argumentummal a listát az utolsó egynéhány parancsra korlátozhatjuk.

Ismétlő történeti parancsok

Ebbe a kategóriába azok a parancsok tartoznak, amelyekkel a felhasználó a történeti listában rögzített parancsokat újra fel tudja használni. Ha a történeti listába az újrafelhasznált parancs nem szövegszerűen kerülne be, hanem history hívást tartalmazva, akkor a további újrafelhasználást megnehezítené, hogy a history hívások (például a relatív sorszámok miatt) mást és mást eredményeznének az eredeti végrehajtáskor és az egyes ismétlések alkalmával. Ezért az ismétlő parancsok a történeti lista legújabb bejegyzését, ha az tartalmaz history hívást, helyettesítik az eredően végrehajtott paranccsal. Így a történeti listát szolgáltató alkalmazásnak elég a felhasználó által beírt parancsot a végrehajtás előtt a történeti listába felvennie, hogy a történeti listába a megfelelő dolgok kerüljenek.
history redo ?hivatkozás?
Végrehajtja a hivatkozott (alapértelmezésben az utolsó) parancsot és visszaadja annak eredményét.
history substitute régi új ?hivatkozás?
A hivatkozott (alapértelmezésben az utolsó) parancsban régi minden előfordulását újra helyettesíti, végrehajtja az így adódó parancsot, és visszaadja az eredményt.
history event ?hivatkozás?
Visszaadja a hivatkozott (alapértelmezésben az utolsó) parancsot.
history words szelektor ?hivatkozás?
Visszaadja a hivatkozott (alapértelmezésben az utolsó) parancs szelektor által meghatározott szavait, egymástól szóközzel elválasztva. Szelektornak három formája megengedett:
  • Egy szám a parancs megfelelő sorszámú szavát jelenti (0 a parancs neve, 1 az első argumentum, és így tovább).
  • Két, egymástól kötőjellel elváslasztott szám az intervallumba eső szavakat jelenti.
  • Egyéb esetben a szelektor a reá a string match parancs szerint illeszkedő szavait jelenti.
Az első két formában a parancs utolsó szavára hivatkozhatunk a '$' karakterrel.
Egyéb parancsok
rename régi új
A rename parancs a régi nevű parancsot átnevezi új nevűre. Ha új üres string, a régi parancs törlődik. A rename üres stringet ad vissza.
time script ?szám?
A time szám-szor (alapértelmezésben egyszer) végrehajtja a megadott scriptet, és visszaad egy
  n microseconds per iteration
alakú stringet, amely a script végrehajtásához szükséges átlagos valós időt jellemzi.
Ismeretlen parancsok
unknown parancsnév ?arg ...?
Amikor a Tcl interpreter nem létező parancs hívásával kerül szembe, megvizsgálja, hogy létezik-e unknown nevű parancs. Ha nem létezik, akkor hibaüzenetet ad vissza. Viszont ha létezik, a Tcl interpreter meghívja, és arugmentumként átadja neki a nem létező parancs nevét és a hívás argumentumait (az átadott argumentumokon már megtörténtek a helyettesítések). Lásd a standard Tcl könyvtárban definiált unknown parancsot.

Standard Tcl változók
A Tcl interpreter definiál több globális Tcl változót. Ezeknek a kezelése az interpreter kizárólagos hatásköre, ezért a kivételektől eltekintve csak olvasni szabad őket.
env
Az env változó egy tömb, amelynek indexei a környezeti változók azonosítói, elemei a megfelelő környezeti változók értékei. A tömb elemeit nemcsak olvasni, hanem írni és törölni is szabad. Egy elem módosítása vagy törlése módosítja vagy törli a hozzárendelt környezeti változót. Az egész tömb törlésével megszűnik a környezeti változókhoz való hozzáférés. Az exec paranccsal végrehajtott alfolyamatok az esetlegesen módosított környezetet öröklik.
errorCode
A Tcl interpreter hiba fellépése esetén az errorCode változóba írt listával részletezi a hiba okát. A lista első eleme adja meg a hiba kategóriáját. A lista további elemeinek száma és jelentése a hiba kategóriájától függ. A Tcl interpreter az alábbi kategóriákat használja:
ARITH kód üzenet
Aritmetikai hiba. A kód adja meg az hiba pontos okát:
DIVZERO nullával való osztás
DOMAIN értelmezési tartományon kívüli argumentum
IOVERFLOW egész aritmetikai túlcsordulás
OVERFLOW lebegőpontos aritmetikai túlcsordulás
UNKNOWN ismeretlen hiba
POSIX hibanév üzenet
POSIX rendszerhívás közben fellépett hiba. A hibanév adja meg a hiba errno.h-ban definiált szimbolikus nevét (például ENOENT). Az üzenet a hiba szöveges jellemzése.
CHILDKILLED azonosító signalnév üzenet
Valamely alfolyamatot egy signal terminálta. Az azonosító az alfolyamat folyamat-azonosítója, signalnév a signal signal.h-ban definiált neve (például SIGPIPE). Az üzenet a signal szöveges leírása.
CHILDSTATUS azonosító kód
Valamely alfolyamat nullától különböző befejezési kóddal terminált. Az azonosító az alfolyamat folyamat-azonosítója, kód a befejezési kód.
CHILDSUSP azonosító signalnév üzenet
Valamely alfolyamatot egy signal felfüggesztette. Az azonosító az alfolyamat folyamat-azonosítója, signalnév a signal signal.h-ban definiált neve (például SIGTTIN). Az üzenet a signal szöveges leírása.
NONE
A hibáról nem áll rendelkezésre részletes információ.

Az errorCode változó tartalmát az error vagy a return paranccsal adhatjuk meg.

errorInfo
Az errorInfo változó egy többsoros stringet tartalmaz, amely feltárja, hogy a hiba hol keletkezett, és milyen parancsok és scriptek végrehajtása szakadt meg miatta. A megszakított parancsok töltik fel, ahogyan a hiba kifelé gyűrűzik.
tcl_precision
A tcl_precision változó értéke azt adja meg, hogy a kifejezések kiértékelésének végeztével a string alakba konvertált eredmény hány szignifikáns jegyet tartalmazzon. Ahhoz, hogy a string alak ne veszítsen az eredmény pontosságából, 17 számjegyre van szükség. Ha a változó nem létezik, akkor értékét a Tcl interpreter 6-nak tekinti.

A standard Tcl könyvtár
A standard Tcl könyvtár a beépített Tcl lehetőségeket terjeszti ki Tcl-ben megírt részekkel. A könyvtárt alkotó fájlokat tároló fájlrendszerbeli könyvtár nevét az info library paranccsal kérdezhetjük le. A könyvtár inicalizálása az ebben található init.tcl végrehajtásával történik. A tclsh ezt automatikusan megteszi helyettünk.

Automatikus betöltés

A standard Tcl könyvtár részét képezi egy olyan unknown eljárás, amely többek között lehetővé teszi definiálatlan eljárások automatikus betöltését. Ehhez a könyvtár több segédeljárást is tartalmaz, amelyek önállóan is használhatók.
auto_mkindex könyvtár minta ?minta ...?
Ahhoz, hogy az automatikus betöltés működjön, az automatikusan betöltendő scripteket tartalmazó könyvtárban létre kell hozzni egy tclIndex nevű indexfájlt, amely megadja, hogy az egyes eljárások definíciója mely fájlban található. Az indexfájl az auto_mkindex paranccsal hozható létre, argumentumként meg kell adni egy könyvtár nevét és egy vagy több fájlnévmintát (utóbbiak értelmezése a glob parancs szerint történik). Az auto_mkindex a megadott fájlokból kikeresi az összes eljárásdefiníciót és elkészíti az indexet.

Az eljárások keresése egyszerű módszerrel történik: az auto_mkindex csak azokat az eljárásdefiníciókat ismeri fel, amelyeknek proc kezdőszava a sor elején áll. Az eljárás neveként az auto_mkindex az ilyen sor második szavát tekinti. Egyéb eljárásdefiníciók (például olyanok, amelyekben a proc előtt szóközök állnak) figyelmen kívül maradnak.

auto_load eljárásnév
Az auto_load parancs megkísérli a megnevezett eljárást betölteni. Az átfésülendő könyvtárakat legmagasabb prioritással a globális auto_path változó határozza meg, melynek tartalma könyvtárnevek listája. Ha az auto_path változó nem létezik, a TCLLIBPATH környezeti változóban tárolt lista adja meg a könyvtárneveket. Ha ez utóbbi sem létezik, akkor a keresés a Tcl könyvtár könyvtárában történik.

Az átfésülendő könyvtárakban az auto_load az auto_mkindex által létrehozott tclIndex fájlban keresi a betöltendő eljárás definíciójának helyét. Ha valamelyikben megtalálja, a megfelelő script fájl végrehajtásával megpróbálja létrehozni az eljárást. Ha sikerül, 1-et ad vissza.

Ha az eljárás betöltése nem sikerül, mert az eljárás nem szerepelt egyik indexfájlban sem, vagy a végrehajtott script nem definiálta az eljárást, az auto_load visszatérési értéke 0. A keresés vagy a betöltendő script végrehajtása közben fellépő hibát az auto_load továbbadja.

Az auto_load a háttértárról csak egyszer olvassa be az indexfájlokat; az indexfájlokból kinyert információt a globális auto_index tömbben tárolja. A tárolt információ törlését az auto_reset paranccsal kényszeríthetjük ki.

auto_execok parancsnév
Az auto_execok parancs eldönti, hogy a létezik-e a megadottal megegyező nevű végrehajtható fájl a PATH környezeti változóban szereplő könyvtárakban. Ha igen, 1-et, különben nullát ad vissza.

A keresett parancsokról az auto_execok a globális auto_execs tömbben megjegyzi, hogy léteznek-e vagy sem, elkerülvén ezzel a háttértáron való ismételt keresést. A tárolt információ törlését az auto_reset paranccsal kényszeríthetjük ki.

auto_reset
Törli az auto_load és az auto_execok parancsok által felhalmazott információkat, valamint az automatikusan betölthetők indexében szereplő eljárásokat. A törölt dolgok újraolvasása a háttértárról igény esetén történik meg.
unknown parancsnév ?arg ...?
Amikor a Tcl interpreter nem létező parancs hívásával kerül szembe, meghívja az unknown eljárást, és arugmentumként átadja neki a nem létező parancs nevét és a hívás argumentumait (az átadott argumentumokon már megtörténtek a helyettesítések). Az unknown sorrendben a következőkkel próbálkozik:
  1. Az ismeretlen parancsot az auto_load segítségével megpróbálja mint eljárást betölteni. Ha ez sikerül, a parancsot megismétli az eredeti argumentumokkal. Ezt a próbálkozást letilthatjuk a globális auto_noload változó létrehozásával.
  2. Ha a betöltés nem járt sikerrel, az auto_execok-val megvizsgálja, hogy létezik-e a paranccsal megegyező nevű végrehajtható fájl. Ha létezik, az exec paranccsal végrehajtja az eredeti argumentumokra. Ezt a próbálkozást letilthatjuk a globális auto_noexec változó létrehozásával.
  3. Amennyiben alfolyamatként sem sikerült a parancsot végrehajtani, és a parancsot a felhasználó adta ki interaktív üzemmódban, két további próbálkozásra kerül sor:
    • Ha a parancs a C-shell jelöléseinek valamelyikével a történeti listára hivatkozik, az unknown történeti helyettesítést hajt végre.
      Jelölés Végrehajtott parancs
      !! az előző parancs
      !n ha n pozitív, az n. parancs, ha negatív, az n-el ezelőtti parancs
      ^régi^új?^? az előző parancs, benne régi minden előfordulása újra helyettesítve
    • Ha a parancs egyéb alakú, és a létező Tcl parancsok valamelyikének egyértelmű prefixe, az unknown kiterjeszti a parancs nevét és meghívja a parancsot az eredeti argumentumokkal.

Ha fenti kísérletek valamelyike sikerrel jár, az unknown az általa végrehajtott parancs visszatérési értékét adja vissza, különben hibát generál.

Műkődése közben az unknown az globális unknown_pending tömbben tartja nyilván, hogy mely eljárások automatikus betöltése van folyamatban. Ennek segítségével ismeri fel, ha az automatikus betöltés végtelen rekurzióba kerül.

Egyéb

parray tömbnév
A parray eljárás a megnevezett tömböt kinyomtatja a standard outputra. A tömbnek a hívó számára láthatónak kell lennie.

Példák

Érdekes Tcl eljárások

# decr változónév ?érték? # Az incr parancs párja. proc decr {name {value 1}} {     upvar 1 $name $name     incr $name [expr - $value] } # sum ?érték ...? # A megadott értékek összegét adja vissza. proc sum {args} {     set s 0     foreach v $args { set s [expr $s+$v]     }     return $s } # do változó kezdő határ törzs # A 'for {set változó kezdő} {$változó <= határ} {incr változó} törzs' ciklus # megfelelője. proc do {varName first last body} {     upvar $varName v     for {set v $first} {$v <= $last} {incr v} { uplevel $body     } } # repeat n törzs # A törzset megismétli n-szer.  Fejlett kivételkezelés. proc repeat {count body} {     global errorInfo errorCode     if {[catch {incr count -1} retval]} then { return -code error $retval     }     while {$count >= 0} { set retcode [catch {uplevel $body} retval] switch $retcode {     0 {}     1 { set trace [split $errorInfo \n] set tracelen [llength $trace] set line3 [lindex $trace [expr $tracelen - 3]] regsub uplevel $line3 repeat line3 set trace [concat [lrange $trace 0 [expr $tracelen - 4]] \ [list $line3]] set errorInfo [join $trace \n] return -code error -errorinfo $errorInfo -errorcode $errorCode\     $retval}     3 {return}     4 {}     default {return -code $retcode $retval} } incr count -1     }     return } # debug változó index művelet # A 'trace variable változónév rwu debug' paranccsal nyomon követi egy változó # olvasását, írását és törlését. proc debug {name element op} {     if {[string compare $element ""] == 0} then { set varname $name     } else { set varname $name\($element\)     }     puts -nonewline "debug: '$varname' was "     puts [switch $op r {expr {"read"}} w {expr {"written"}} u {expr {"unset"}}]     if {[string compare $op u] != 0} then { upvar $varname x puts "debug: '$varname' = '$x'"     } }

Egy önálló Tcl programocska

#!/bin/sh # Simple Tcl implementation of grep. \ exec tclsh "$0" "$@" proc grep {prefix file} {     global argv     set pattern [lindex $argv 0]     while {[gets $file line] >= 0} { if {[regexp -- $pattern $line]} then {     puts "$prefix$line" }     } } if {$argc < 1} {     error "Usage: tgrep pattern ?fileName?" } if {$argc == 1} then {     grep "" stdin } else {     foreach fname [lrange $argv 1 end] { set file [open $fname r] grep "$fname:" $file close $file     } }

Kiegészítések, módosítások: Sarlós Tamás, Nagy Viktor