A Tcl programozási nyelv

Típusok, típuskonstrukciók

Stringek

A string a Tcl egyetlen valódi adattípusa. A parancsok argumentumai és visszatérési értékei is stringek. A további adattípusokat (listák, számok) is stringekkel reprezentálja.

tcl8.0   8.0-tól kezdve már a Tcl_Obj struktúrákon alapul az adatok tárolása, így a stringeké és a listáké is. Ez hatékony tárolást tesz lehetővé, és elkerülhetők a felesleges konverziók.

Egyszerű stringműveletek

A stringműveletek nagy részét a string parancs valósítja meg.

string művelet arg ?arg ..?
Az első argumentummal választjuk ki a műveletet, a további argumentumok szintaxisát az egyes műveletek külön-külön határozzák meg. A műveletekben közös, hogy a string karaktereit nullától kezdve indexelik.

string index string index
A megadott string indexedik karakterét adja vissza. Ha nullánál kisebb vagy a string hosszánál nem kisebb indexet adunk meg, az eredmény üres string.

string range string kezdet vég
A megadott string kezdet és vég indexek közé eső részét adja vissza. Második indexként megadhatunk end-et is, ami a string utolsó karakterének indexét jelenti. Ha kezdet kisebb nullánál, nullának, ha vég nem kisebb a string hosszánál, end-nek számít. Ha kezdet nagyobb végnél, üres string az eredmény.

string length string
A megadott string hosszát adja vissza.

string wordstart string index
Az index indexen álló karaktert tartalmazó szó első karakterének indexét adja vissza. Egy szónak a string összefüggő, alfanumerikus és aláhuzáskarakterekből álló, és az egyetlen egyéb karakterből álló részstringjei számítanak.

string wordend string index
Az index indexen álló karaktert tartalmazó szó utolsó karaktere mögötti karakter indexét adja vissza.

string trim string ?törlendő?
A megadott string elejéről és végéről a törlendő karakterek eltávolításával előálló stringet adja vissza. Törlendő alapértelmezése a szóköz, a tabulátor, az újsor és a kocsivissza karakter.

string trimleft string ?törlendő?
Mint a string trim parancs, de csak a string elejéről töröl.

string trimright string ?törlendő?
Mint a string trim parancs, de csak a string végéről töröl.

string tolower string
A nagybetűket kisbetűkre cserélve adja vissza a megadott stringet.

string toupper string
A kisbetűket nagybetűkre cserélve adja vissza a megadott stringet.

string compare string1 string2
A karakterek ASCII kódja szerinti lexikális összehasonlítást végez két stringen. A -1, 0 vagy 1 értéket adja vissza aszerint, hogy az első string kisebb, egyenlő vagy nagyobb a másodiknál.

string first minta string
Minta első előfordulását keresi meg stringben. Ha ez létezik, az előfordulás első karakterének indexét, ha nem, -1-et ad vissza.

string last minta string
Minta utolsó előfordulását keresi meg stringben. Ha ez létezik, az előfordulás első karakterének indexét, ha nem, -1-et ad vissza.

string match minta string
Egyet vagy nullát ad vissza aszerint, hogy string illeszkedik-e mintára vagy sem. A minta karakterei a velük azonos karakterekre illeszkednek, a következők kivételével:

* Tetszőleges - akár üres - részstringre illeszkedik.
? Tetszőleges karakterre illeszkedik.
[karakterek] A szögletes zárójelek között megadott karakterekre illeszkedik. Ha karakterekben két karakter között kötőjel áll, az ASCII kód értelmében a két karakter közé eső karakterekre is illeszkedik.
\x Az x karakterre illeszkedik. Így semlegesíthetjük a *?[]\ karakterek speciális jelentését.

Formázott stringek

A Tcl rendelkezésünkre bocsát egy stringformázó parancsot, amelyet a C programozási nyelv könyvtárából ismert sprintf függvényhez hasonlóan használhatunk:

format séma ?arg ...?
Az első argumentum, a séma adja meg az eredményként visszaadott formázott string vázát, és hogy a további argumentumokat hol és milyen alakban kell a vázban elhelyezni. A séma közönséges karakterei változtatás nélkül az eredmény részévé válnak, a '%' karakterrel kezdődő konverziós specifikációk helyére pedig az argumentumok íródnak, megfelelő alakra konvertálva.

A sémát követő argumentumok a séma konverziós specifikációinak sorrend szerint felelnek meg. Legtöbb specifikációhoz egy argumentum tartozik, de vannak kivételek.

A konverziós specifikáció a '%' karakter mögött az alábbi táblázatban ismertetett elemeket tartalmazhatja, a megadott sorrendben:

Argumentum-pozíció
Egy természetes szám és egy '$' karakter alkotja. Azt adja meg, hogy a specifikációhoz tartozó első argumentum hányadik argumentum-pozíción áll (a továbbiaknak, ha vannak, ezt kell követniük). A sémát követő első argumentum pozíciója az 1-es. Két lehetőségünk van: vagy egyáltalán nem használunk explicit argumentum-pozíciókat, és ekkor sorrend szerinti megfeleltetés történik, vagy pedig minden specifikációban megadjuk a pozíciót.

Jelzők halmaza
A következő karakterekből állhat (sorrendjük egymás között tetszőleges):
# Alternatív konverzió. 'o' konverziónál: az eredményben az oktális szám mindenképpen nullával fog kezdődni. 'x' illetve 'X' konverzió: az eredményben a hexadecimális szám "0x"-szel illetve "0X"-szel fog kezdődni. 'e', 'E', 'f', 'g' és 'G' konverzió: az eredményben a lebegőpontos szám mindenképpen tartalmazni fog tizedespontot. 'g' és 'G' konverziónál előzőeken kívül: az eredmény tartalmazni fogja a "felesleges" nullákat is.
0 A konvertált érték balról nullákkal töltődik fel a megadott szélességre.
- A konvertált értéket a megadott szélességen belül baloldalra igazítja. Hatástalanítja a '0' jelzőt.
szóköz Előjeles konverzióban ('d', 'e', 'E', 'f', 'g', 'G' és 'i'): pozitív számok előtt egy szóközt hagy szabadon az előjel helyén.
+ Előjeles konverzióban: Minden (akár nemnegatív) szám elé ír előjelet. Hatástalanítja a szóköz jelzőt.

Szélesség
Természetes szám. Azt adja meg, hogy a konvertált érték legalább hány karaktert foglaljon el. Ha a konvertált érték ennél rövidebb, akkor töltelékkarakterekkel egészül ki (alapértelmezésben balról szóközökkel, de a '-' és '0' jelzőkkel ezt felülbírálhatjuk).

Pontosság
Nemnegatív egész szám. Jelentése a konverziótól függ:
d, i, o, u, x, X Az eredmény számjegyeinek minimális számát adja meg (szükség esetén a szám balról nullákkal egészül ki).
e, E, f A tizedespont mögé írt számjegyek számát adja meg.
g, G A szignifikáns számjegyek maximális számát adja meg.
s Az eredményben megjelenő karakterek maximális számát adja meg (az argumentum szükség esetén jobbról csonkolódik).

Típusjelző
Alábbiak közül választhatunk:
h Hatására a 'd', 'i', 'o', 'u', 'x' vagy 'X' konverzió előtt az argumentum értéke C short típusának megfelelően csonkolódik.
l A format parancs figyelmen kívül hagyja.

Konverzió
A konverziós specifikáció egyetlen kötelező eleme. A következők állnak rendelkezésünkre:
d, i, o, u, x, X Az egész szám argumentumot előjeles decimális számként ('d' és 'i'), előjel nélküli oktális számként ('o'), előjel nélküli decimális számként ('u') vagy előjel nélküli hexadecimális számként ('x' - abcdef betűkkel, és 'X' - ABCDEF betűkkel) jelenik meg az eredményben. Ha pontosság is adott, akkor balról nullákkal egészül ki a konvertált szám a megfelelő mennyiségű számjegyre.
e, E A lebegőpontos argumentumot [-]d.dddeddd ('e') illetve [-]d.dddEddd ('E') alakú decimális számra konvertálja és kerekíti, ahol egy számjegy előzi meg a tizedespontot, a tizedesjegyek száma pedig megegyezik a pontossággal (ha nincs megadva: hattal). Ha a pontosság nulla, nem jelenik meg tizedespont. Az 'e'/'E' utáni szám legalább kétjegyű.
f A lebegőpontos argumentumot [-]ddd.ddd alakú decimális számra konvertálja és kerekíti. A tizedesjegyek száma megegyezik a pontossággal (ha nincs megadva: hattal), ha a pontosság nulla, nem jelenik meg tizedespont. Ha van tizedespont, legalább egy számjegy lesz előtte.
g, G A lebegőpontos argumentumot 'f' vagy 'e' illetve 'E' konverzió szerint konvertálja. A pontosság a szignifikáns jegyek számát adja meg. Ha nem adott, az alapértelmezés 6; ha nulla, akkor egynek számít. Az 'e' vagy 'E' konverziót akkor használja, ha az exponens -4-nél kisebb vagy nem kisebb a pontosságnál. A tizedesjegyek közül elhagyja a felesleges nullákat, és tizedespont csak jelenik meg az eredményben, ha azt legalább egy tizedesjegy követi.
c Az egész szám argumentumot az általa megadott ASCII-kódú karakterre konvertálja.
s A string argumentumot változatlanul az eredménybe másolja. Ha a pontosság adott, akkor legfeljebb ennyi karaktert másol (jobbról csonkol).
% Egy '%' karaktert jelent.
A numerikus konverziókban az argumentumoknak egész vagy lebegőpontos számot reprezentáló stringeknek kell lenniük. Ezeket a format parancs binárisra konvertálja, majd a konverziós specifikációnak megfelelően vissza stringgé.

Például a '%2$-10.8hd' specifikációban a '$2' egy argumentumpozícíó, a '-' egy jelző, a '10' a szélesség, a '8' a pontosság, az 'h' egy típusmódosító, a 'd' pedig a konverziót szabja meg.

A szélességet és/vagy a pontosságot megadó szám helyett szerepelhet egy '*' is, ekkor az adott értéket a konverzió tárgyát megelőző egy vagy két egész szám argumentum adja meg.

A format parancs az ANSI C sprintf függvényétől az alábbiakban különbözik:

Stringek sscanf-szerű elemzése

A Tcl nemcsak a C könyvtár sprintf függvényének megfelelő format parancsot implementálja, hanem egy, a sscanf függvénynek megfelelő parancsot is:

scan string séma változónév ?változónév ...?
Az scan parancs a format-tal analóg elemző függvény, egy séma string alapján elemzi, konvertálja és tárolja a nevükkel megadott változókban az adatokat.

Az scan egyfajta mintaillesztést végez a string és a séma között, az argumentumokban megnevezett változókba bizonyos illesztett részek konvertáltjai kerülnek. A parancs visszatérési értéke azt adja meg, hogy hány argumentumot sikerült feltöltenie. Ezen érték és az argumentumok számának összevetésével eldönthető, hogy a string megfelelt-e a sémának.

Az séma közönséges karaktereket és '%' karakterrel kezdődő konverziós specifikációkat tartalmaz. A séma minden fehér karaktere a string fehér karaktereinek elvetését jelenti a következő nem fehér karakterig. Az eldobott karaktereknek nem kell megegyeznie a sémában szereplővel. A séma egyéb, konverziós specifikációnak nem részét képező karaktereinek pontosan meg kell egyeznie a string karaktereivel, különben illesztési hiba lép fel. A konverziós specifikációkra illeszkedő részek a specifikációra jellemző konverzió után a sorrendben következő változónak adódnak értékül.

A konverziós specifikáció a '%' karakter mögött az alábbi táblázatban ismertetett elemeket tartalmazhatja, a megadott sorrendben:

Jelzők
Egyetlen jelzőt használhatunk:
* Csak az illesztést hajtja végre, de a konvertált értéket eldobja, nem használ argumentumot.

Szélesség
Azt adja meg, hogy legfeljebb hány karaktert kell a konvertálandó string részeként tekinteni. Ha nincs megadva, az alapértelmezés végtelen. A string illesztése az első nem illeszkedő karakternél, de legkésőbb a szélesség elérése után áll meg. A legtöbb konverzió az illesztés előtt eldobja a fehér karaktereket, ezek nem számítanak bele a szélességbe.

Típusmódosító
A C programozási nyelvvel való kompatibilitás érdekében 'h' vagy 'l' megadható, de a scan parancs figyelmen kívül hagyja.

Konverzió
A következők állnak rendelkezésünkre (ahol nincsen más megadva, a konverzió az illesztés előtt eldobja a soron következő fehér karaktereket):
% Egy '%' karakterre illeszkedik. Konverzió és értékadás az argumentumokba nem történik.
d Egy előjeles vagy anélküli decimális egészre illeszkedik.
i Egy előjeles vagy anélküli egészre illeszkedik. Az egészt hexadecimálisként értelmezi, ha az "0x"-szel vagy "0X"-szel kezdődik, oktálisként, ha nullával kezdődik, különben pedig decimálisként. Csak a számrendszernek megfelelő számjegykaraktereket fogad el.
o Egy oktális egészre illeszkedik.
u Egy előjel nélküli decimális egészre illeszkedik.
x Egy előjel nélküli hexadecimális egészre illeszkedik.
e, f, g Egy előjeles vagy anélküli lebegőpontos számra illeszkedik.
s Nem fehér karakterek sorozatára illeszkedik.
c Egyetlen karaktert illeszt, és ASCII-kódjára konvertálja. Konverzió előtt nem dobja el a soron következő fehér karaktereket.
[ Megengedett karakterek nemüres sorozatára illeszkedik. Konverzió előtt nem dobja el a soron következő fehér karaktereket. A megengedett karakterek a '[' karakter és a lezáró ']' karakter között megadottak, például "[abc]". Ha a '['-t közvetlenül '^' követi, akkor a megengedett karakterek a fel nem soroltak lesznek, például "[^0123456789]". A ']' karaktert úgy adhatjuk meg, hogy közvetlenül a '[' vagy '^' mögé írjuk. A kötőjel karakterrel egész intervallumot adhatunk meg, például "[0-9A-Fa-f]". A kötőjel karaktert a ']' elé írva elveszti speciális szerepét. Az illesztésnek az első nem megengedett karakter (vagy a maximális szélesség) elérésekor van vége.

Az illesztés mindig a lehető legnagyobb hosszon történik, például egy '%d' specifikáció illesztése akkor fejeződik be, ha a következő karakter számjegytől különböző, vagy már a szélességben megadott darabszámú karakter illeszkedett.

A scan parancs az ANSI C sscanf függvényétől a következőkben tér el:

Listák

A lista nagyon általános és kényelmesen használható adatszerkezet, nem véletlen, hogy több programozási nyelvben is, például a LISP-ben vagy a Prologban, központi helyet foglal el. A Tcl is erősen épít a listákra, még akkor is, ha nem láncoltan, hanem stringekre visszavezetve ábrázolja őket.

Tulajdonképpen már a Tcl alapjait tárgyaló fejezetben megjelenik, hogy a listát milyen módon reprezentálják a stringek, ugyanis a lista szintaxisa megegyezik a parancséval. A különbség mindössze annyi, hogy az alkotókat nem szavaknak, hanem elemeknek nevezzük, és hogy a listában nincsen értelmezve változó- és parancshelyettesítés.

Az idézőjelek és a kapcsos zárójelek a szóközöket tartalmazó listaelemek egybefogására valók, például:

   első második {szóközt tartalmaz} negyedik
Célszerűbb a kapcsos zárójeleket használni, mert azok az idézőjelekkel szemben egymásbaágyazhatók:
   első második {beágyazott {beágyazottba ágyazott} lista} utolsó
A backslash lehetővé teszi, hogy a listaelemek idézőjeleket vagy kapcsos zárójeleket tartalmazzanak:
   idézőjel \" nyitó \{ záró \}
Amikor parancs részeként adunk meg listát, kapcsos zárójelekkel kell leárnyékolnunk a helyettesítésektől:
   set l {egy két há négy}
A listák elemeit Tcl-ben nullától kezdve indexelik, vagyis a lista első eleme a nulladik indexű.

Listák létrehozássa

Listát legegyszerűbben az elemeiből hozhatunk létre a

list ?elem ...?
paranccsal. A list az elem argumentumokból álló listát adja vissza (argumentumok híján üres stringet). Az elemeket megfelelő módon kiegészíti kapcsos zárójelekkel és backslash-ekkel, ha szóközöket vagy speciális karaktereket tartalmaznak.

Már létező listákat a

concat ?lista ...?
parancs fűzi össze újabbakká. Ehhez a concat parancs argumentumai elejéről és végéről eltávolítja a szóközöket, majd egy-egy szóközzel összeragasztja őket.

Listák módosítása

linsert lista index elem ?elem ...?
Az linsert parancs egy vagy több elemet szúr be listába az index-edik elem elé, és visszaadja az így keletkező új listát. Ha index nulla vagy negatív, akkor az elemek a lista elejére kerülnek. Ha end-et, vagy a lista elemeinek számánál nem kisebb értéket adunk meg indexnek, az elemek a lista végéhez fűződnek hozzá.

A lista végéhez fűzés gyakori speciális esete a listába történő beszúrásnak, ezért ezt egy külön parancs is támogatja:

lappend változónév ?elem ...?
Az lappend adott változóban tárolt listához fűz hozzá tetszőleges számú elemet. Ha a változó még nem létezik, akkor a felsorolt elemeket tartalmazó listaként jön létre. A lappend parancs - különösen hosszú listák esetén - sokkal hatékonyabban működik, mint a concat vagy linsert parancsok, mert a listát nem másolja le fizikailag.

lreplace lista kezdet vég ?elem ...?
Az lreplace parancs törli listából a kezdet indextől a vég indexig az elemeket, beszúrja helyükre a megadottakat, és visszaadja az így keletkező új listát. Ha nem adunk meg elemeket, értelemszerűen csak törlés történik. Ha kezdet negatív, a lista első elemét jelöli. Vég nem lehet kisebb kezdetnél. Mindkét index helyén állhat end, ami a lista utolsó elemét jelenti.

Listák lekérdezése

llength lista
Ez a parancs lista elemeinek számát adja vissza.

lindex lista index
Az lindex parancs lista index+1. elemét adja vissza. Ha a hivatkozott index nem szerepel a listában, üres string az eredmény. Index lehet end is, ez az utolsó elemet jelenti.

lrange lista kezdet vég
Az lrange lista kezdet és vég indexek közé eső részét adja vissza. Mindkét index lehet end. Kezdet nullának számít, ha negatív, és vég end-nek, ha nagyobb vagy egyenlő a lista elemeinek számával.

Ha a két egyenlő indexet adunk meg, az eredmény akkor is egy lista lesz; például kapcsos zárójelek közé lesz zárva, ha tartalmaz szóközöket.

Keresés listákban

lsearch ?illesztés? lista minta
Az lsearch parancs mintának megfelelő elemet keres listában. Ha talál, az első illeszkedő elem indexét, ha nem talál, -1-et ad vissza. Az illesztés argumentum határozza meg, hogy mintát hogyan kell értelmezni:
-exact
A listaelemnek azonosnak kell lennie a mintával.
-glob
A minta a string match parancsban megengedett minta, és az illesztés ennek értelmében történik. Ez az alapértelmezés.
-regexp
A minta egy reguláris kifejezés, és az illesztés a regexp parancsnak megfelelő.

Listák rendezése

lsort ?kapcsolók? lista
Az lsort parancs a lista rendezett permutációját adja vissza. A rendezés módját kapcsolókkal adhatjuk meg:
-ascii
Lexikografikus rendezés ASCII-kód szerint. Ez az alapértelmezés.
-integer
Egész számokat tartalmazó lista numerikus rendezése.
-real
Lebegőpontos számokat tartalmazó lista numerikus rendezése.
-command parancs
Rendezés parancs szerint. Két elem összehasonlításához a parancsból és a két elemből álló script fut le. A scriptnek negatív értéket, nullát, vagy pozitív értéket kell visszaadnia aszerint, hogy az első elem rendre kisebb, egyenlő vagy nagyobb a másodiknál.
-increasing
Rendezés növekvő sorrendben. Ez az alapértelmezés.
-decreasing
Rendezés csökkenő sorrendben.
tcl8.0  
-dictionary
Szótári rendezést valósít meg. Abban különbözik az -ascii rendezéstől, hogy nem különbözteti meg a kis- és nagybetűket (csak teljes egyezés esetén), és a stringbe ágyazott számokat számként és nem karakterekként hasonlítja össze.
-index index
Listák listájának rendezése esetén mely elemeket hasonlítsa össze az allistákból.

Listák és stringek közötti konverzió

split string ?elválasztók?
A split parancs stringet feldarabolja az elválasztók stringben megadott karakterek közé eső részekre, és visszaadja a részeket tartalmazó listát. Ha string első vagy utolsó karaktere elválasztókarakter, vagy két elválasztókarakter közvetlenül egymás mellett szerepel benne, a lista megfelelő elemei üres stringek lesznek. Az alapértelmezett elválasztókarakterek a fehér karakterek. Például
   split heureka.inf.elte.hu .
eredménye 'heureka inf elte hu'.

join lista ?összekötő?
A join parancs lista elemeit az összekötő stringgel egyetlen stringgé köti össze, amelyet visszaad. Az összekötő alapértelmezésben egy szóköz.

Tömbök kezelése

array művelet tömbnév ?arg ...?
Az array parancs több tömbbel kapcsolatos műveletet egyesít. Első argumentumában a konkrét műveletet, a másodikban az érintett tömb nevét adjuk meg.

Tömb jellemzőinek lekérdezése

array exists változónév
Egyet ad vissza, ha a változónév tömböt azonosít, nullát, ha egyszerű változót takar vagy nem létezik ilyen nevű változó.

array size tömbnév
A tömb elemeinek számát adja vissza. Ha nem tömb nevét adjuk meg, a visszatérési érték nulla.

array names tömbnév ?minta?
A tömb elemei indexeinek listáját adja vissza. Ha megadunk egy mintát, a lista csak azon indexekre terjed ki, amelyek a string match parancs értelmében illeszkednek a mintára. Ha nem tömbváltozóra adjuk ki a parancsot, a visszatérési érték üres lista (string).

Konverzió tömb és lista között

array get tömbnév ?minta?
A tömb elemeit és azok indexeit tartalmazó listát ad vissza. A listában az indexet a hozzá tartozó érték követi. Az index-érték párok sorrendje egymáshoz képest nem definiált. Ha megadunk egy mintát, a lista csak azon indexekre terjed ki, amelyek a string match parancs értelmében illeszkednek a mintára. Ha nem tömbváltozóra adjuk ki a parancsot, a visszatérési érték üres lista (string).

array set tömbnév lista
Index-érték párok szerint értékadást hajt végre a tömbön. A listának páros számú elemet kell tartalmaznia. A párok első eleme adja meg a tömb azon indexét, amelynek új értéke a második elem lesz.

Tömb elemeinek bejárása

array startsearch tömbnév
Előkészíti a tömb bejárását és visszaad egy bejárási azonosítót, amellyel a továbbiakban a bejárásra hivatkozhatunk. A bejárási azonosítók réven lehetőségünk van egy tömbön egyszerre tömb bejárást is folytatni. A bejárás automatikusan befejeződik, ha a tömböt új elemmel bővítjük.

array anymore tömbnév azonosító
Egyet ad vissza, ha a bejárás során még nem érintettünk minden tömbelemet, különben nullát.

array nextelement tömbnév azonosító
A bejárás szerint következő tömbelem indexét adja vissza. Ha már minden tömbelemet érintettünk, a visszatérési érték üres string. Ez nem különböztethető meg attól az esettől, amikor maga a tömb következő elemének indexe üres string. Ezért használjuk az array anymore parancsot, ha az üres string előfordulása az indexek között nem kizárható.

array donesearch tömbnév azonosító
Befejezi a bejárást és felszabadítja a bejárás nyilvántartáshoz szükséges erőforrásokat. A visszatérési érték üres string.

Kifejezések, operátorok

A Tcl nem elsődleges szinten vezeti be a kifejezés fogalmát, hanem a kifejezésekkel paraméterezhető parancsoknál.

expr arg ?arg ...?
A kifejezésekhez legszorosabban kötődő parancs az expr, amelynek egyetlen funkciója, hogy argumentumai konkatenáltját, mint Tcl kifejezést, kiértékelje, és az eredményt visszaadja. Az expr parancs természetes helye a parancshelyettesítésekben van, például:
   set x [expr 2*$y + $z]
Az expr-en túli kifejezésekkel paraméterezhető parancsok is - mint például a vezérlőszerkezet-parancsok, amelyeknek a vezérlési feltételt kifejezéssel adjuk meg - mind az expr-rel azonos módon kezelik a kifejezéseket. Ezért foglalkozzunk először a konkrét parancsoktól függetlenül a Tcl kifejezésekkel.

A Tcl kifejezések nagyon hasonlítanak a C programozási nyelv kifejezéseire. A Tcl operátorai a C operátorainak részhalmazát alkotják, precedenciájuk és jelentésük megegyezik a megfelelő C operátorokéval. Akár a C-ben, a Tcl-ben sem számítanak az operandusok, operátorok és zárójelek közötti szóközök. A C-ből átvett lehetőségeken kívül a Tcl kifejezésekben mód nyílik még helyettesítések alkalmazására, valamint stringek összehasonlítására relációs operátorokkal.

Operandusok

A Tcl és C kifejezések közötti egyik különbség az operandusok megadásának módjában van. A Tcl kifejezések operandusaiban például megengedettek az alábbi helyettesítések:

Meg kell jegyezni, hogy ezeket a helyettesítéseket a kifejezést kiértékelő parancs hajtja végre, függetlenül a parancs végrehajtását megelőző helyettesítési fázistól. Ezért célszerű a kifejezéseket kapcsos zárójelbe zárni, hogy csak egy menetben történjen helyettesítés.

A helyettesítés után Tcl egész számként próbálja meg értelmezni az operandusokat, ha azok számjeggyel kezdődnek. Egész számokat megadhatunk decimálisan (ha az operandus első karaktere '1'-'9'), oktálisan (ha az operandus első karaktere '0') vagy hexadecimálisan (ha az operandus első két karaktere '0x').

Ha az operandus számjeggyel kezdődik, de nem felel meg az egész számok szintaxisának, a Tcl lebegőpontos számként próbálja elfogadni. Ugyanazokat a megadási módokat használhatjuk, mint amelyeket az ANSI C szabvány meghatároz (kivéve az 'f', 'l' vagy hasonló szuffixeket, amelyeket a legtöbb Tcl interpreter nem támogat).

Szintaktikus hibának számít, ha az operandus számjeggyel kezdődik, de nem egész vagy lebegőpontos szám. A nem számjeggyel kezdődő operandusokat a Tcl stringként kezeli, de csak akkor, ha a string a kifejezésekben támogatott helyettesítések valamelyikéből származik.

Lehetőségünk van továbbá matematikai függvények alkalmazására is, amelyek argumentumai tetszőleges Tcl kifejezések lehetnek, például 'fmod($x,$y)'.

Operátorok és precedencia

Következzenek a Tcl operátorai csökkenő precedencia szerint.

-  +  ~  !
Negatív és pozitív előjeloperátor, bitenkénti negáció, logikai tagadás. Ezek az operátorok nem alkalmazhatók stringekre, és a bitenkénti negáció csak egészekre alkalmazható.

*  /  %
Szorzás, osztás, maradék. Ezek az operátorok nem alkalmazhatók stringekre, és a maradékoperátor csak egészekre alkalmazható. A maradék előjele azonos az osztóéval és abszolút értéke kisebb az osztóénál.

+  -
Összeadás és kivonás. Csak numerikus operandusokra alkalmazható.

<<  >>
Balra és jobbra léptetés. Csak egész operandusokra alkalmazható.

<  >  <=  >=
Kisebb, nagyobb, kisebb vagy egyenlő és nagyobb vagy egyenlő relációs operátorok. Az operátorok 1-et adnak eredményül, ha a reláció fennáll, 0-át különben. Ezek az operátorok számokra és stringekre egyaránt alkalmazhatók.

==  !=
Egyenlő és nem egyenlő. Mindkét operátor eredménye 0 vagy 1. Tetszőleges típusú operandusra alkalmazhatók.

&
Bitenkénti ÉS. Csak egészekre alkalmazható.

^
Bitenkénti KIZÁRÓ VAGY. Csak egészekre alkalmazható.

|
Bitenkénti VAGY. Csak egészekre alkalmazható.

&&
Logikai ÉS. Eredménye 1, ha egyik operandusa sem nulla, különben 0. Csak numerikus operandusokra alkalmazható.

||
Logikai VAGY. Eredménye 0, ha mindkét operandusa nulla, különben 1. Csak numerikus operandusokra alkalmazható.

x ? y : z
Ha x kiértékelve nem nullát ad, az eredmény az y eredménye, különben a z eredménye. Az x operandusnak numerikusnak kell lennie.

A bináris operátorok azonos precedencián belül balról jobbra kötnek.

Az &&, || és ?: operátorok lusta kiértékelésűek, mint C-ben, vagyis nem értékelődik ki az összes operandus, ha a kifejezés értéke már az operandusok egy részének kiértékelése után meghatározható. Ez nem feltétlenül teljesül, ha a kifejezést nem zártuk kapcsos zárójelek közé, mert a parancs meghívása előtt már történhetnek helyettesítések a kifejezés tetszőleges részeiben.

Matematikai függvények

A Tcl kifejezésekben a következő, a C könyvtárban is szereplő matematikai függvényeket használhatjuk:

   acos    atan2   cosh    fmod    log10   sinh    tanh
   asin    ceil    exp     hypot   pow     sqrt    
   atan    cos     floor   log     sin     tan
Ezek a függvények az azonos nevű C könyvtári függvény meghívásával számítják ki az eredményt. A Tcl a további függvényeket definiálja még:

abs(x) Az x abszolút értékét adja vissza. Az x lehet egész vagy lebegőpontos, az eredmény típusa ennek megfelelő.
double(x) Ha x lebegőpontos érték, egyszerűen visszaadja, különben lebegőpontosra konvertálja és úgy adja vissza.
int(x) Ha x egész, egyszerűen visszaadja, különben csonkítással egészre konvertálja és úgy adja vissza.
round(x) Ha x egész érték, egyszerűen visszaadja, különben kerekítéssel egészre konvertálja és úgy adja vissza.
tcl8.0   A 8.0-s verzióban használhatóak a rand() és srand(x) véletlenszám-generáló függvények, amelyek megegyeznek az azonos nevű C könyvtári függvényekkel.

A kiértékelés részletei

A Tcl a kifejezés kiértékelés közben C típusokat használ, az egészeket long, a lebegőpontos számokat double értékekkel reprezentálja. A stringgel adott operandusok int-re vagy double-ra történő konverziója során fellépő túl- és alulcsordulások észlelése a Tcl fordításához használt C könyvtáron múlik, ezért ahol ez lényeges, ne erre alapozzunk. A közbülső eredmények esetében is C-beli viszonyok uralkodnak, vagyis az egészek túl- és alulcsordulásáról általában nem kapunk információt, a lebegőpontos számok esetében a hardver adta lehetőségek többnyire jobbak, ezekben bízhatunk.

A kiértékelés közben a Tcl egészeket használ, amíg lehetséges, és csak lebegőpontos operandus előfordulása esetén tér át lebegőpontos számokra.

A kiértékelés végeztével az eredmény string alakba konvertálódik. Ha az eredmény lebegőpontos típusú, akkor a string tartalmazni fog egy tizedespontot ('.') és egy 'e' betűt, hogy ez kifejezésre jusson. Alapértelmezésben hat szignifikáns jegy szerepel a lebegőpontos eredmény stringre konvertált alakjában. Ha a tcl_precision nevű globális változó létezik, akkor az adja meg a szignifikáns jegyek számát.

Bár a Tcl lehetővé teszi stringek összehasonlítását kifejezésekben, jobban járunk, ha a string compare parancsot használjuk. Ugyanis abban az esetben, ha az egyik operandus számként értelmezhető, az összehasonlítás előtt azt a Tcl előbb számmá konvertálja, majd vissza stringgé. Így például az 'expr {"0x11" < "0z11"}' parancs eredménye 0, mert az összehasonlítás valójában '17' és '0z11' között zajlik.

Reguláris kifejezések

Egy reguláris kifejezés bizonyos stringek halmazát adja meg. Ha egy string eleme egy reguláris kifejezéssel megadott halmaznak, azt mondjuk, hogy a reguláris kifejezés illeszkedik a stringre. Gyakran arra vagyunk kíváncsiak, hogy a reguláris kifejezés egy adott string mely részstringjeire illeszkedik.

Egy reguláris kifejezés az aritmetikai kifejezésekhez hasonlóan operandusokból és operátorokból áll, azzal a különbséggel, hogy az operandusok halmazok, és az operátorok halmazműveletek. A halmazműveleteknek van precedenciájuk, amelyet zárójelek használatával felülbírálhatunk.

A reguláris kifejezések elemei csökkenő precedencia szerinti sorrendben a következők:

Atom
Az atom zárójelek közé zárt reguláris kifejezés vagy az alábbiak valamelyike:
. Tetszőleges egy karakternyi stringre illeszkedik.
^ Az illesztett string első karaktere elé képzelt üres stringre illeszkedik. Használatával elérhető, hogy a reguláris kifejezés csak a string elejét is tartalmazó részstringekre illeszkedjen.
$ Az illesztett string utolsó karaktere mögé képzelt üres stringre illeszkedik. Használatával elérhető, hogy a reguláris kifejezés csak a string végét is tartalmazó részstringekre illeszkedjen.
\c A 'c' karakterre illeszkedik. Így adhatunk meg speciális jelentéssel bíró karaktereket közönséges karakterként.
c A 'c' karakterre illeszkedik. A 'c' nem lehet reguláris kifejezésekben speciális jelentéssel felruházott karakter.
[karakterek] A szögletes zárójelek között felsorolt karakterek valamelyikéből álló, egy hosszúságú stringre illeszkedik. Ha a nyitó szögletes zárójelt '^' követi, a fel nem sorolt karakterekre illeszkedik. Karakterek ASCII-kód szerinti intervallumát adjuk meg, ha a zárójelek között két karaktert kötőjellel kötünk össze (akár több kötőjelet is használhatunk, például '[0-9A-F]'). A ']' karaktert úgy adjuk meg, hogy közvetlenül a kezdő '[' vagy '^' karakter mögé írjuk. A '-' karaketert úgy, hogy a záró ']' elé írjuk. A '^' karaktert pedig úgy, hogy nem a '[' mögé írjuk.

Lezárt
A darab egy atom, amelyet opcionálisan egy postfix operátor követ. A postfix operátorokat és jelentésüket mutatja be ez a táblázat:
* Az operandus atomra illeszkedő elemekből álló véges (akár üres) sorozatra illeszkedik.
+ Az operandus atomra illeszkedő elemekből álló véges nemüres sorozatra illeszkedik.
? Az operandus atomra és az üres stringre illeszkedik.

Konkatenált
Nulla, egy vagy több közvetlenül (szóköz nélkül) egymás után írt darabból áll. A darabokra illeszkedő stringek konkatenáltjára illeszkedik.

Unió
Nulla, egy vagy több '|' karakterrel elválasztott konkatenált alkotja. A konkatenáltak valamelyikére illeszkedő stringekre illeszkedik.

Reguláris kifejezés szerinti keresés

regexp ?kapcsolók? kifejezés string ?egész? ?rész ...?
A regexp parancs eldönti, hogy egy reguláris kifejezés illeszkedik-e egy string valamely részére vagy egészére, és 1-et ad vissza, ha igen, 0-át, ha nem.

A string után megadhatunk változóneveket. A regexp parancs az első változónak a string illeszkedő részét adja értékül. A további változókba sorrendjüknek megfelelően a reguláris kifejezés zárójelezett részkifejezéseire illeszkedő részstringek másolódnak.

Ha az első változónév mellett több változónevet adunk meg, mint ahány zárójelezett részkifejezése van a reguláris kifejezésnek, vagy ha valamelyik zárójelezett részkifejezés nem a kifejezés illeszkedő részében volt (például egy unió nem illeszkedő tagjában), akkor a megfelelő változó értéke az üres string lesz.

Előfordulhat, hogy a reguláris kifejezés többféleképpen illeszkedik a stringre. Ekkor prioritásuk sorrendjében a következő szabályok szerint dől el, hogy mely illeszkedés szerint töltődnek fel a változók:

  1. Különböző pozíción kezdődő illeszkedő részstringek közül az előbb kezdődő illesztődik.
  2. Az úniókban a legelső illeszkedő konkatenált illesztődik.
  3. A lezártakban a lehető leghosszabb illeszkedő rész illesztődik.
  4. A konkatenáltak elemeinek feldolgozása balról jobbra történik.
A parancs működését kapcsolókkal módosíthatjuk:
-nocase
Az illesztésnél a string nagybetűit kisbetűnek tekinti.
-indices
A változókba nem az illeszkedő részstringeket másolja, hanem olyan kételemű listákat, amelyek első eleme az illeszkedő rész első, második eleme a rész utolsó karakterének stringbeli indexe. Az üres stringeket a '-1 -1' lista reprezentálja.
--
A kapcsolók sorának végét jelzi. A következő argumentum már nem számít kapcsolónak, még ha kötőjellel kezdődik is.

Reguláris kifejezés szerinti helyettesítés

regsub ?kapcsolók? kifejezés string helyettesítő változónév
A regsub parancs egy string valamely reguláris kifejezésre illeszkedő részét helyettesíti, és az eredményt a megadott változónak adja értékül. A parancs a helyettesített részek számát adja vissza.

A helyettesítőben hivatkozhatunk az illeszkedő rész egészére és részeire is. A '&' és a '\0' az egész illeszkedő részt jelenti. Az '\n', ahol n 1 és 9 közötti számjegy, a reguláris kifejezés n-edik zárójelezett részkifejezésére illeszkedő részt adja meg. Célszerű ezt az argumentumot kapcsos zárójelekkel megvédeni a Tcl backslash-helyettesítésével szemben.

A parancs működését kapcsolókkal befolyásolhatjuk:

-nocase
Az illesztésnél a string nagybetűit kisbetűnek tekinti. A helyettesítésben a string hivatkozott illeszkedő részei ettől függetlenül eredeti formájukban jelennek meg.
-all
Az összes illeszkedő részen elvégzi a helyettesítést. Ezen kapcsoló nélkül a parancs csak az első előfordulást helyettesíti.
--
A kapcsolók sorának végét jelzi. A következő argumentum már nem számít kapcsolónak, még ha kötőjellel kezdődik is.

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.