|
INTRODUCTIE
Bine ati venit la acest indrumator Tcl. L-am scris cu scopul de a ajuta la invatarea in Tcl. Este cu scopul pentru cei care au cateva cunostinte depre programare, cu toate ca nu trebuie sa fii cu siguranta un expert. Acest indrumator intentioneata sa va insoteasca catre manualul Tcl , pagini care furnizeaza referinte despre toate comenzile Tcl.
Este impartit in scurte sectiuni acoperind diferite aspecte ale limbii. Depinde pe ce retea esti, poti oricand sa te uiti in referinta pentru o documentare a unei comenzi de care esti curios. Pe unix de exemplu , in timp ce am 'aduce' sus pagina initiala pentru comanda intreaga.
Fiecare sectiune este insotita de exemple relevante cate iti arata cum sa pui in folosinta materialul respectiv.
SURSE ADITIONALE
Comunitatea Tcl este exagerat de pretentioasa. Este frumos din partea ta daca incerci lucrurile de unul singur, dar daca nu intelegi, suntem acolo ca sa te ajutam.
Aici sunt cele mai bune locuri sa ceri ajutor:
La comp.lang.tcl newsgroup. Acesibil via newsreader , sau Grupuri Google
Wiki are o buna distribuire a codului, exemple si discutii ale celor mai bune puncte ale pacticarii Tcl.
Daca ai nevoie de ajutor imediat, pe canalul #tcl vei gasi mereu pe irc.freenode.net care te poate ajuta, dart e rog sa nu-ti pierzi cumpatul daca nimeni nut e va ajuta pe moment - daca aveti nevoie de nivelul de suport, considerati a angaja un consultant.
Sunt mai multe carti recomandate pentru cei care vor sa patrunda in cunoasterea Tcl-ului. Clif Flynt original autor al acestui indrumator este si autor al Tcl/Tk: A Developer's Guide. Alte care folositoare : Practical Programming in Tcl and Tk.
CREDITE
Multumim prima data si celui dintai lui Clif Flynt, facand acest material valabil sub o licienta BSD. Multumiri si urmatorilor : Neil Madden, Arjen Markus, David N. Welton
Desigur , asteptam comentarii si sugestii despre cum poate fi imbunatatit - sau este bun asa, nu ne deranjeaza putinele multumiri.
Text Simplu Produs
Traditionalul start plasat pentru indrumator este programul "Hello, world". Odata ce poti tipari un String, esti pe drumul cel bun in folosirea Tcl-ului pentru distractie si profit.
Comanda pentru a produce un Sting in Tcl este comanda puts.
O singura unitate de text dupa comanda puts va fi tiparita la mecanismul de producere standard ( in acest caz, in fereastra de jos ). Lispa comportamentului este sa tipareasca o noua linie caracter ("intoarcere") potrivita pentru system dupa tiparirea textului.
Daca stringul are mai mult decat un cuvant, trebuie sa cuprinzi stringul in ghilimele sau o acolade (). Un set de cuvinte cuprinse in ghilimele sau acoladele sunt considerate ca o singura unitate, cat timp cuvintele sunt separate prin spatiu se considera mai multe argumete la comanda. Ghilimele si acoladele pot fi folosite in mai multe grupuri de cuvine intr-o singura unitate. Oricum, ele se vor purta diferit. In lectia urmatoare veti invata diferentele in comportamentul lor. Nota in Tcl, o singura ghilimea nu este semnificanta, cum sunt in programarile C, Perl si Pyton.
Multe comenzi ale Tcl-ului (incluzand puts) pot accepta mai multe argumente. Daca un string nu este cuprinsa intre ghilimele sau acolade, interpretul Tcl-ului va considera fiecare cuvant in parte fiind argument.si trece la fiecare individual comanda puts. Comanda puts va incerca sa evalueze fiecare cuvant ca un argument optional. Aceasta probabil va rezulta o eroare.
O comanda din Tcl este o lista de cuvinte terminate intr-o singura line sau de punct si virgula (;). Comentariile in Tcl sunt cu # la inceputul fiecarei linii, sau terminarea comenzii se face cu punct si virgula (;).
ATRIBUIREA UNEI VALORI LA O VARIABILA
In Tcl, totul poate fi reprezentat ca un string, cu toate ca in interior poate fi reprezentat ca o lista, intreg, dublu, sau alt tip, pentru a face sa mearga limba mai repede.
Atribuirea in Tcl se face cu ajutorul comenzii set.
Cand set este chemat de doua argumente can in :
set fruit 'Cauliflower'
plasarea celui de al doilea argument ('Cauliflower') in memorie spatiul se refera pentru primul argument (fruit). Set intotdeauna se intoarce la continutul primei variabile numita in primul argument si apoi se intoarce la al doilea. In exemplul de mai sus, pentru moment, se va intoarce la 'Cauliflower', fara ghilimele.
Primul argument la comanda set poate fi oricare singur cuvant, ca fruit sau pi sau poate fi un membru al unui array. Despre arrays vomd discuta mai multe mai tarziu, pentru moment amintiti-va ca mai multe date pot fi numite sub un singur nume de variabila, si ca data individuala poate fi accesata de indexul cuprins in acel array. Indexand in acel array in Tcl este manevrat de punerea indexului intre paranteze dupa numele variabilei.
Set poate fi invocat cu un singur argument. Cand este chemat cu un singur argmument, se va intoarce la continutul acelui argument.
Aici un mic rezumat despre comanda set :
Set varNAME? value?
if value este specificat, atunci continutul variabilei varNAME este egal cu value.
if varNAME consta in numai caractere aflanumerice, si nici o paranteza, este o variabila scalara.
if varNAME are forma varNAME(index) , este un membru asociat array.
Daca ne uitam in exemplul code, vei observa ca in cadrul comenzii set primul argument este tiparit numai cu numele lui, dar cand declaram puts este precedat cu $.
Semnul dolarului comanda Tcl-ului sa ia valoarea din variabila - in acest caz X sau Y.
Tcl trece date la fiecare subrutina de la nume sau de la valuare. Comenzile care nu schimba continutul variabilei uzuale au argumente proprii trecute in valoare.
Exemplu
EVALUAREA SI SUBSTITUIREA 1 : GRUPAREA ARGUMETELOR CU GHILIMELE ""
Aceasta lectie este una din cele trei despre care vom discuta cum Tcl-ul manevreaza substituirea in timpul preluarii comenzii.
In Tcl, preluarea unei comenzi se face in in doua faze. Prima faza este unica trecere a substituirii. Cea de a doua faza este preluarea rezultatului comenzii. Numai unul trece de substituirea facuta. Astfel in comandaputs
$varName, continutul variabilei adecvate este inlocuita pentru $varNAME, si apoi comanda este exacutata. Asumand ca avem set varNAME la "Hello World" , secventa va fi vazuta asa: puts varNAME
⇒ puts "Hello World" , care este executat si tiparita Hello World.puts 'The current stock value is $varName', continutul current pentru varNAME este substituit pentru $varNAME, si intregul string este tiparit la procedeul de productie, ca si in exemplul de mai sus.
In general, backslash-ul (), opreste substituirea pentru un character imediat urmat de backslash. Orice alt character urmat imediat de un backslash va sta fara substituire.
Oricum, este specific "Secventa backslash", stringul care este inlocuit de o valuare specificain timpul fazei de substituire. Urmatoarele stringuri backslash vor fi inlocuite cum sunt aratate mai jos:
String
Output
Hex Value
a
Audible Bell
0x07
b
Backspace
0x08
f
Form Feed (clear screen)
0x0c
n
New Line
0x0a
r
Carriage Return
0x0d
t
Tab
0x09
v
Vertical Tab
0x0b
0dd
Octal Value
d is a number from 1-7
xhh
Hex Value
h is a hex digit 0-9,A-F,a-f
Exemplu
set Z 'Albany'
set Z_LABEL 'The Capitol of New York is: '
puts '$Z_LABEL $Z';# Prints the value of Z
puts '$Z_LABEL $Z' ;# Prints a literal $Z instead of the value of Z
puts 'nBen Franklin is on the $100.00 bill'
set a 100.00
puts 'Washington is not on the $a bill' ;# This is not what you want
puts 'Lincoln is not on the $$a bill';# This is OK
puts 'Hamilton is not on the $a bill' ;# This is not what you want
puts 'Ben Franklin is on the $$a bill' ;# But, this is OK
puts 'n.. examples of escape strings'
puts 'TabtTabtTab'
puts 'This string prints out non two lines'
puts 'This string comes out
on a single line'
EVALUARI SI SUBSTITUIRI 2 : GRUPAREA ARGUMENTELOR CU ACOLADE
In timpul fazei de substituire a comenzii evaluate, cele doua grupuri operatoare, acoladele () si ghilimele (""), sunt tratate diferit de catre interpretul Tcl.
In lectia precendenta ati observat ca gruparea cuvintelor in ghilimele lasa substituirea sa se petreaca in ghilimele. Grupand cuvinte cuprinse intre doua acolade opresc substituirea cuprinsa intre ghilimele. Caracterele cuprinse intre acolade sunt trecute in comanda exact cum sunt scrise. Numai "Secventa Backslash" care proceseaza in interiorul acoladelor au backslash la fiecare sfarsit de linie. Aceasta este tot o prelungire a caracterului.
Tineti minte ca acoladele
au effect numai cand sunt folosite pentru grupuri (i.e. la inceput si la
sfarsitul unei secvente de cuvinte). Daca un string este deja grupat, fie cu
ghilimele fie cu acolade, si acoladele sunt in mijlocul stringului grupat (i.e.
"foo
puts 'n. examples of differences in nesting '
puts
puts 'n.. examples of escape strings'
puts
puts
EVALUARI SI SUBSTITUIRI 3 : GRUPAREA ARUMENTELOR CU PARANTEZE PATRATE []
Poti obtine rezultatul unei comenzi punand comanda in paranteze patrate ([]). Este un echivalent functional al aprotrofului ( ` ) in programarea sh, sau folosind valoarea de intoarcere a unei functii in C.
Asa cum un Tcl interpret citeste in fiecare linie se schimba toate $variables cu valorile lor. Daca o portie din string este grupat in paranteze patrate, atunci stringrul dintre parantezele patrate este evaluat ca o comanda de catre interpret si rezultatul inlocuieste paranteze patrate string.
Sa luam urmatorul segment ca exemplu:
puts
[readsensor [selectsensor]]]
O analiza a comenzii, se vede ca este o commanda pentru
executarea substituirii: readsensor [selectsensor]
, care este trimisa catre interpret pentru evaluare.
Analizand inca odata gasim o comanda care sa fie evaluate
si substituita, selectsensor.
Fictive comanda selectsensor
este evaluata, si dupa cum se pare se intoarce la sensor sa fie citit.
In acest moment,
readsenzor are un sensor de citit, si readsenzor este comanda evaluate.
In final, valoarea de la
readsenzor este trecuta in spatele comenzii puts, care este tiparita pe ecran.
Exceptiile are regulei sunt urmatoarele:
O paranteza patratacare este scapata de un este considerate ca o paranteza patrata literala.
O paranteza patrata intre acolade nu este modificata in timpul substitutiei.
Exemplu
set x 'abc'
puts 'A simple substitution: $xn'
set y [set x 'def']
puts 'Remember that set returns the new value of the variable: X: $x Y: $yn'
set z
puts 'Note the curly braces: $zn'
set a '[set x ]'
puts 'See how the set is executed: $a'
puts '$x is: $xn'
set b '[set y ]'
puts 'Note the escapes the bracket:n $b is: $b'
puts '$y is: $y'
REZULTATUL UNEI COMENZI - MATH 101
Comanda Tcl pentru a face operatii de tip matematice este expr. Urmatoarea discutie o vom avea despre comanda expr extrasa si adaptata de pe pagina principala.
Expr ia toate din argumentele ("2+2" de exemplu) si evalueaza recultatul ca Tcl "expresie" (mai mult decat o comanda normala) si se intoarce la valoare. Operatorii permint in expresiile Tcl sa includa toate funtiile matematice standarde, operatori logici, operatori bitwise, la fel ca si funtiile mathematice ca rand() , sqrt() , cosh() si altele. Expresiile aproape mereu produc rezultate numerice (interger sau valori floating-points)
Tip de performare: cuprinzand toate argumentele din expr in acolade va rezulta un cod mai rapid. Deci poti sa faci expr inloc de expr $i * 10.
OPERANZII
O expresie Tcl consta intr-o combinatie de operanzi, operatori si paranteze. Spatiul poate fi folosint intre operanzi, operatorii si parantezele: este ignorata de catre expresia procesorului. Unde este posibil ca operanzii sa fie interpretati ca valori integer. Valorile integer poti decimale (in cazuri normale), octal (daca caracterul operandului este 0 zero), sau hexadecimale (daca primele doua caractere ale operandului sunt 0x).
Nu uitat ca transformarea octalului si decimalului au loc in diferite locuri ale comenzii expr in faza de substituire a Tcl-ului. In faza de substituire, x32 poate fi convertit in ascii "2", cat timp expr poate converta 0x32 in 50 de decimale.
Daca un operand nu are una din formatele integer date mai sus, atunci este tratata ca un numar floating-points, daca este posibiil. Numerele floating-points pot fi specificate in una din caile acceptate de un ANSI-compiliant compilatorul C. De exemplu toate din urmatoarele numere floating-points sunt valide: 2.1, 3., 9.91e+16. Daca interpretarea numerica nu este posibila, atunci operandul este lasat ca un string (si numai un set limitat de operatori se vor aplica pentru el).
Operanzii pot fi specificati in mai multe forme:
Ca o valuare numerica, interger sau floatin-points.
Ca o variabila Tcl, folosint notatii standard $. Valoarea variabile va fi folosita de catre operand.
OPERATORII
Operatorii care sunt valizi sunt listati mai jos:
Unary minus, unary plus, bit-wise NOT, logical NOT. Nici unul din acesti operatori nu poate fi aplicat la un operand string, si bit-wise NOT poate fi aplicat numai in integer
Inmultire, impartire, rest. Nici unul din acesti operatori poate fi aplicat la un operand string, dar restul poate fi aplicat numai la integer, restul va avea intotdeauna acelasi semn ca ce al divizorului, si o valoarea absoluta mai mica decat a divizorului.
adunare si scadere. Sunt valide pentru operanzi numerici.
<< >> Valid pentru operanzii integer.
& bit-wise AND. Valid pentru operanzi integer.
^bit-wise exclusiv OR. Valid pentru operanzi integer.
| bit-wise OR. Valid pentru operanzi integer.
&& Logical AND. Produce un singur rezultat daca ambii operanzi sunt non-zero, sau chiar 0. valid pentru oepranzii numerici (integer sau floating-points).
Logical AND. Produce 0 rezultate, daca ambii operanzi sunt zero, altmiteri 1.
x?y:z if-then-else, exact ca in C.daca valuarea lui x este diferita de zero, atunci rezultatul este valuarea lui y. Altmiteri este rezultatul valorii lui z. Operandul x trebuie sa aiba o valoare numerica.
FUNCTII MATEMATICE
Tcl-ul suporta urmatoarele functii matematice:
acos coshypotsinh
asin cosh log sqrt
atan explog10tan
atan2 floor pow tanh
ceil fmod sin
TIPURI DE CONVERSIUNI
Tcl-ul suporta urmatoarele functii de convertire de la reprezentarea unui numar la altul :abs double int round
Exemplu
set X 100;
set Y 256;
set Z [expr '$Y + $X']
set Z_LABEL '$Y plus $X is '
puts '$Z_LABEL $Z'
puts 'The square root of $Y is [expr sqrt($Y)]n'
puts 'Because of the precedence rules '5 + -3 * 4'is: [expr -3 * 4 + 5]'
puts 'Because of the parentheses'(5 + -3) * 4' is: [expr (5 + -3) * 4]'
puts 'n.. more examples of differences between ' and
puts '$Z_LABEL '
puts 'The command to add two numbers is: [expr $a + $b]'
COMPARATORI NUMERICI 101 - IF
Ca in majoritatea limbilor, Tcl-ul o comanda daca este scrisa asa:
if expr1 ?then? body1 elseif expr2 ?then? body2 elseif ?else? ?bodyN?
Cuvintele then si else sunt optionale, cu toate ca in general then este lasat si else este folosit.
Un test al expresiei urmarind if va trebui sa rezulte una din urmatoarele:
fals adevarat
o valuare numerica 0 toate celelalte
yes/no no yes
true/false false true
Daca expresia returneaza "yes"/"no" sau "true"/"false", cazul de returnare nu este verificat. True/FALSE sau YeS/nO, sunt raspunsurile bune.
Daca evaluarea testului este True, atunci body1 va fi executat.
Daca evaluarea testului este False, urmatorul cuvant dupa body1 va fi examinat. Urmatorul cuvant este elseif, atunci urmatoarea expresie a testului va fi testate ca o conditie. Daca urmatorul cuvant este else atunci cuvantul body va fi evaluat ca o comanda.
Expresia testului urmata de cuvantul if este evaluate in aceiasi maniera ca in comanda expr
Expresia testului urmat de if poate cuprinde ghilimele, acolade. Daca este cuprinsa in interiorul acoladelor, o sa fie evaluate in interiorul comenzii if, daca if cuprinde ghilimeleva fi evaluate in tipul fazei de substitutie, si apoi alta repriza de substituiri vor fi facute in interiorul comenzii if.
Exemplu
set x 1
if else
if else
if $x==1
set y x
if '$$y != 1' else
COMPARAREA TEXTULUI - SWITCH
Comanda switch te lasa sa-ti alegicateva optiuni pentru codul tau. Este similara cu switch din C, cu o exceptie ca e mai flexibila, pentru ca poti sa "switch" stringuri, inloc de interger. Stringul va fi comparat cu un set de modele, si daca un model seamana cu acel string, codul asociat cu acel model vor fi evaluate.
E o idée buna sa folosesti comanda switch cand vrei sa potrivesti o variabila impotriva multor valori posibile, sin u vrei sa faci o lunga serie de if.elseif.elseif.
Comanda se scrie asa:
switch string
pattern1 body1 ?pattern2 body2? ?patternN bodyN?
- sau -
switch string
String este stringul pe care doresti sa-l testezi, si pattrn1, pattern2,etc sunt modelelecare stringul le va compara. Daca string se potriveste cu un model, atunci codul din body asociat cu acel model vor fi executate. Valuarea returnata din body va fi returnata ca valoarea returnata din afirmatiile switch. Numai un model se va potrivesti.
Daca ultimul argument pattern este un default string, atunci modelul se va potrivi cu orice string. Aceasta garanteaza ca, cateva din setarile codului vor fi executate indiferent de continutul stringului.
Daca nu este nici un argument default, si nici un model care sa se potriveasca cu acel string, atunci comanda switch va returna un string gol.
Daca folosesti versiunea comenzii cu acolade,nu vor exista substituiri facute in model. Corpul comenzii,totusi, va fi analizat si evaluat la fel ca fie care comanda, si acolo va fi o trecere a substitutiei facute acolo, la fel va fi facuta si in prima sintaxa. Avntajul formei a doua este ca poti sa scrii multiple comenzi pe o singura linie citite cu parantezele patrate.
Nota: poti folosi acolade pentru a grupa argumentul body cand folosim comenzi cum ar fi switch si if. Aceasta pentru ca aceste comenzi trec argumentul body la interpretul Tcl pentru evaluare. Aceasta evaluare include o trecere a substitutiei asa cum se face pentru cod nu in interiorul comenzii argumentului body.
Exemplu
set x 'ONE'
set y 1
set z 'ONE'
# This is probably the easiest and cleanest form of the command
# to remember:
switch $x
ONE
TWO
THREE
default
switch $x '$z' ONE TWO THREE default
switch $x 'ONE' 'puts ONE=1' 'TWO' 'puts TWO=2' 'default' 'puts NO_MATCH'
switch $x
'ONE' 'puts ONE=1'
'TWO' 'puts TWO=2'
'default' 'puts NO_MATCH';
Tcl include doua comenzi pentru looping, while si for. La fel ca afirmatia if ele evalueaza testul lor exact la fel cum face si expr. In aceasta lectie vom discuta despre comanda while si in lectia urmatoare despre comanda for. In majoritatea circumstantelor unde una din aceste comezi poate fi folosita, si cealalta poate fi folosita de asemenea.
while
test
body
Comanda while evalueaza textul ca o expresie. Daca test este adevarat, atunci body poate fi executat. Dupa ce codul din body a fost executat, test va fi evaluat din nou.
Afirmatia continue cuprinsa in body va opri executia codului si test va fi reevaluat. Break cuprins in body va intrerupe while bucla. Si executia va continua cu o noua linie a codului dupa body.
In Tcl everything este o comanda, si everything trece prin aceiasi faza de substituire. Pentru un motiv, test trebui trecut intre acolade. Daca test este trecut intre ghilimele, faza de substituire va inlocui orice variabila cu valoare curenta, si va trimite acel test la comanda while pentru evaluare, si de atunci test va avea numai numere, si cu probabil desavarsire va conduce la un final al buclei !
Uitati-va la cele doua bucle din exemplu. Daca nu era o comanda break in a doua bucla, buclarea era continua.
Exemplu
set x 1
# This is a normal way to write a Tcl while loop.
while
puts 'exited first loop with X equal to $xn'
# The next example shows the difference between '..' and
# How many times does the following loop run? Why does it not
# print on each pass?
set x 0
while '$x < 5' break
if '$x > 3' continue
puts 'x is $x'
puts 'exited second loop with X equal to $x'
Buclarea 102 - For si incr
Tcl sustine loop-ul repetat format similar loop-ului for din C. Comanda for din Tcl este formata din patru argumente: o initiere, un test, o crestere si corpul codului de evaluat la fiecare trecere prin loop. Sintaxa pentru comanda for este :
for start test next body
In timpul evaluarii comenzii for,codul start este evaluat o singura data, inaintea evaluarii oricarui alt argument.Dupa ce codul start a fost evaluat, urmeaza evaluarea codului test. Daca test este dovedit a fi adevarat, codul body este evaluat si ,in sfarsit, incepe evaluarea codului next. Dupa evaluarea argumentului next, interpretul se intoarce la test si repeta procesul. Daca testul se dovedeste a fi fals, atunci loop-ul va iesi imediat.
Start este portiunea de initializare a comenzii. De obicei este folosita pentru a porni variabila repatarii,dar care poate contine orice cod pe care doriti sa il porniti inainte de inceperea loop-ului.
Argumentul test este evaluat ca o expresie, la fel ca si in comenzile expr while si if.
Next este o comanda comuna de crestere, dar poate contine orice comanda pe care interpretul Tcl o poate evalua.
Body este corpul codului de executat.
Pentru ca in mod normal nu se doreste ca faza de substituire a interpretului Tcl sa schimbe variabilele la valorile sale curente inainte de a trece controlul pentru comanda for, este normal sa se grupeze argumentele in legaturi ondulate. Cand sunt folosite legaturi pentru grupare, linia noua nu este tratata ca finalul unei comenzi Tcl . Astfel, devine mai simplu sa se foloseasca comenzi din linii multiple. Totusi, legatura de inceput trebuie sa fie pe aceeasi linie cu comanda for sau ,in alt caz interpretul Tcl va considera inchizatura legaturii next ca sfarsitul comenzii si va rezulta o eroare. Asta este diferit fata de alte limbaje ca C sau Pearl unde nu conteaza unde se pun legaturile.
In codul body, comenzile break si continue pot fi folosite ca si comanda while. Cand o comanda break este intalnita, loop-ul iese imediat.Cand o comanda continue apare, evaluarea body-ului stagneaza si test este reevaluat. Pentru ca sporirea variabilei repeterii este asa de comuna, Tcl are si o comanda speciala pentru asta
incr varName ?increment?
Aceasta comanda adauga valoarea in al doilea argument la variabila numita in primul. Daca nu este data nici o valoare celui de-al doilea argument ,totul va scadea la 1.
ADAUGANG COMENZI NOI IN TCL - PROC
In Tcl nu exista nici o distinctie intre comenzi( deseori cunoscute ca "functii" in alte limbi) si "sintaxa". Nu exista cuvinte speciala (ca if sau while), asa cum exista in C, Java, Python, Pearl etc..Cand interpretul Tcl incepe, exista o lista de comenzi pe care acesta le foloseste pentru a analiza o linie. Aceste comenzi includ while, for, set, puts etc..Totusi, exista si niste comenzi Tcl uzuale care raspund acelorasi reguli de sintaxa ca toate comenzile Tcl, ambele construite si cele pe care le creezi chiar tu cu ajutorul comenzii proc.
Comanda proc creeaza alta comanda.Sintaxa pentru comanda proc este:
proc name args body
Cand proc este evaluata, se creeaza o noua comanda cu numele name care presupune argumente args. Cand incepe procedura name, porneste si codul continut de body.
Args este lista argumentelor care vor trece la name. Cand name este invocat, vor fi creeate variabile locale cu aceste nume si variabilele care urmeaza a trece la name vor fi copiate la variabilele locale.
Valoarea pe care body-ul unui proc o returneaza poate fi definitivata cu ajutorul comenzii return. Comanda return va returna argumentul sau la programul initiator. Daca nu exisat nici un raspuns, body-ul se va intoarce la initiator atunci cand ultima comanda a fost executata. Valoare de inapoiere a ultimei comenzi devine valoarea de inapoiere a procedurii.
Variatii in argumentele proc si valorile de intoarcere
O comanda proc poate fi definita cu ajutorul unui numar scazut de argumente necesare (asa cum s-a intamplat si cu sum in lectiile anterioare) sau poate avea un numar variabil de argumente. De asemenea un argument poate fi definit ca posesorul unei valori lipsa.
Variabilele pot fi definite cu o valoare scazuta prin plasarea numelui variabilei si absenta in interiorul acoladelor cuprinse in arument si predefinitul in legaturi in args. De exemplu:
Din moment ce exista argumente
predefinite pentru variabilele b si c, procedura poate fi numita in trei
modalitati : justdoit 10,
care ar fixa a la 10 si ar lasa b la valorea normala de 1 si c la -1. In alt caz, justdoit 10 20 ar
seta b la 20 si ar lasa c la valoarea sa normala.
Un proc va accepta un numar variabil de argumente daca ultimul argument notat contine cuvantul args. Daca ultimul argument al unui argument proc este args, atunci oricare argumente care nu sunt deja atribuite unei variabile anterioare vor fi atribuite lui args.
Procedura exemplu de mai jos este definita cu trei argumente. Macar un argument "trebuie" sa fie prezent cand este strigat example. Al doilea argument poate fi exclus, iar in acel caz va scadea la un rand gol. Prin numirea lui args ca ultim argument,example poate avea un numar variabil de argumente.
A se retine ca daca exista o alta variabila in afara lui args dupa o variabila cu o scadere,
atunci scaderea nu va fi niciodata folosita. De exemplu, daca numesti un proc
asa : proc function c}
,
mereu va trebui sa il sustii cu trei argumente.
Tcl atribuie valori unor variabile ale unui proc in ordinea in care sunt aliniate in comanda. Daca dai 2 argumente cand numesti function acestea vor fi atribuite lui a si b, iar Tcl va genera o eroare pentru ca c este nedefinit
You can, however, declare other arguments that may not have values as coming after an argument with a default value. For example, this is valid:
proc example args}
In acest caz, example
are nevoie de un singur argument care va fi atribuit variabilei required. Daca
exista doua argumente, al doilea ii va fi atribuit lui default1.
Daca exista 3 argumente, primul ii va fi atribuit
lui required, al doilea lui default1,iar al treilea lui default2.
Daca un exemplu este
numit cu mai mult de trei argumente, toate argumentele dupa al treilea vor fi
atribuite lui args.
Variabila scope - global si upvar
Tcl evalueaza un nume variabil din interiorul celor doua domenii: domeniul local din interiorul unui proc si un domeniu global (codul si variabilele din exteriorul unui proc). Ca si C, Tcl defineste numai un singur domeniu global.
The scope in which a variable will be evaluated can be
changed with the global
or upvar
command. Domeniul in care o variabila va fi evaluata poate fi schimbat cu
ajutorul omenzilor global si upvar.
Comanda global va cauza evaluarea variabilei in domeniul global in locul celui local.
Comanda upvar are un comportament similar. Upvar asociaza numele unei variabile din domeniul curent cu o variabila dintr-un domeniu diferit. Este o metoda uzuala pentru a simula referinta de trecere la procs.
Sintaxa pentru upvar
este:
upvar ?level? otherVar1 myVar1 ?otherVar2 myVar2 ?
Upvar
face ca myVar1 sa
devina referinta lui otherVar1 si
ca myVar2 sa devina referinta lui otherVar2, etc. Cealalta
variabila otherVar este declarata a fi la un nivel relativ la
procedura curenta current . Prin scadere nivelul 1 este urmatorul nivel.
Daca un numar est folosit pentru un nivel atunci referintele de nivel se fac la urmatoarele nivele care se aduna dupa nivelul curent.
Daca numarul level-ului este prcedat de simbolul # atunci referinta se face multe scaderi de la domeniul global. Daca level este #0 atunci referirea este la o variabila la un nivel global.
Parerea mea personala este ca folosind un upvar cu orice in afara de #0 sau 1 inseamna creearea unro probleme.
Folosirea globalului este greu de evitat, dar trebuie evitat a avea multe variabile globale. Daca se incepe a avea nevoie de multe globale. Ar trebuie sa fie revizuit designul.
A se observa ca pentru ca exista numai un singur spatiu global este surprinzator de banal faptul ce exista conflicte de nume daca se importeaza codurile altor persoane si acestea nu sunt atente. Este recomandabil a se incepe variabilele globale cu un prefix identificabil pentru a ajuta la evitarea unor conflicte.
STRUCTURI DE DATE TCL - LISTA
Lista este o structura de baza in Tcl. O lista este pur si simplu o colectie ordonata de lucruri, numere,cuvinte, linii etc. De exemplu, o comanda in Tcleste doar o lista in care prima intrare este numele unui proc, iar urmatorii memebrii din lista sunt argumente la proc.
Listele pot fi creeata prin diferite metode :
prin schimbarea unei variabile intr-o lista de valori
set lst }
with the split command
set lst [split 'item 1.item 2.item 3' '.']
with the list command.
set lst [list 'item 1' 'item 2' 'item 3']
Un membru individual din lista poate fi accesat cu ajutorul comenzii lindex.
Descrierea sumara a acestor comenzi este:
list ?arg1 arg2 ?
makes a list of the arguments
split string ?splitChars?
Divide randul intr-o lista de item la splitChars SplitChars scade pentru a incepe un spatiu nou. A se observa ca daca exista doua splitchars-uri unul dupa altul in randul divizat, atunci fiecare va fi analizat ca marcand o intrare in lista si va crea o intrare goala in lista.. Daca splitchars este un rand, atunci fiecare membru al randului va fi folosit pentru a divide string in membrii ai listei. Ie:
split '1234567' '36']
intr-o lista compusa din .
lindex list index
returneaza itemul index din lista. Primul item este 0.
llength list
Inapoiaza numarul de elemente dintr-o lista.
Itemii listei pot fi repetati folosind comanda foreach.
foreach varname list body
Foreach va executa codul body o singura data pentu fiecare itemi ai listei din list. Piecare pass, varname va contine valoarea urmatorului list item.
Adaugarea si stergerea membrolor din lista
Comanda pentru a adauga si a sterge membrii este
concat ?arg1 arg2 argn?
Inlantuie args-urile intr-o singura lista. De asemenea elimina spatiile de inceput si uramtoare din args si adauga un singur spatiu de separare intre agrs .Args-urile la concat pot fi ori elemente individuale,ori liste. Daca un arg este deja o lista , continutul acelei liste este inlantuit cu celealte args-uri .
lappend listName ?arg1 arg2 argn?
Anexeaza args-urile la lista listName tratand fiecare arg ca un element al listei.
linsert listName index arg1 ?arg2 argn?
Inapoiaza o noua lista cu noi listari inserate chiar inainte de elementul index al listName-ului. Fiecare elememt argument va deveni un element separat al noiii liste. Daca indexul este mai mic sau egal cu zero, atunci noile elemente sunt inserate la inceputul listei. Daca indexul are ultima valoare sau daca este mai mare sau egal cu numarul de elemente din lista, atunci noile elemente sut anexate la lista.
lreplace listName first last ?arg1 argn?
Inapoiaza o noua lista cu N listName elemente inlocuite de args. Daca intaiul este mai putin sau egal cu 0, atunci Ireplace incepe a inlocui inca de la primul element din lista. Daca intaiul este mai mare decat sfarsitul listei sau decat cuvatul sfarsit, atunci Ireplace se comporta ca sectionat. Daca exista mai putini args decat numarul de pozitii dintre prima si ultima, atunci pozitiile pentru care nu exista args sunt sterse.
A se observa codul exemplu si a se oferi o atentie accentuata modului in care grupuri de caractere sunt asezate in liste individuale de elemente.
Mai multe comenzi ale listei - lsearch, lsort, lrange
Listele pot fi cautate cu comande lsearch, sortate cu comanda lsort ,iar un sir de intrari in lista pot si extrase cu ajutorul comenzii lrange.
lsearch list pattern
Cauta in lista o intrare care ii corespunde lui pattern si returneaza indicele pentru prima potrivire sau a-1 daca nu exista corespondenta.
lsort list
Sorteaza lista si inapoiaza o noua lista in ordinea aranjata. Prin scadere aranjeaza lista in ordine alfabetica.
lrange list first last
Returneaza o lista compuse din primul pana la ultima intrare in lista. Daca primul este mai putin sau egal cu 0, el este tratat ca fiind primul element. Daca ultimul este sfarsit sau o valoare mai mare decat numarul de elemente din lista, el este tratat ca fiind sfarsitul. Daca primul este mai mare decat ultimul atunci o lista goala este inapoiata.
Prin scadere lsearch foloseste o metoda sferica de a gasi o corespondenta. Globbing este metoda de wildcard pe care majoritatea shell-urilor de Unix o folosesc.
globbing wildcards sunt:
Potriveste orice cantitate a oricarui element
Potriveste orice intamplare a oricarui caracter
X Backslash-ul trece cu vederea un caracter special la fel cum o face si in substitutiile tcl. Folosirea backslash-ul permite folosirea sferei pentru a potrivi un * sau ?.
Gaseste orice intamplare a oricarui element situat intre paranteze. Un rand de caractere pot fi potrivite folosind un sir dintre paranteze. De exemplu: [a-z] se va potrivi cu orice litera dintr-o grupa mai mica.
String Subcommands - length index range
O caracteristica a lui Tcl este ca si comenzile pot avea subcomenzi. String este un astfel de exemplu. Comanda string trateaza primul argument ca fiind o subcomanda. Lectia acopera aceste subcomenzi string:
string length string
Inapoiaza lungimea unui sir
string index string index
Returns the char at the index'th position in string
string range string first last
Inapoiaza un rand compus,de la primul pana la ultimul caracter
String comparisons - compare match first last wordend
Exista 6 subcomenzi string care fac potrivire dintre modele si randuri.
string compare string1 string2
Compara string1 cu string2 si rezulta
-1 .. If string1 e mai mica decat string2
0 .. If string1 e egala cu string2
1 .. If string1 e mai mare ca string2
Aceste comparatii sunt facute lexicografic si nu numeric/
string first string1 string2
Inapoiaza index-ul elementului din string1 care incepe prima procedura cu string2 sau -1 daca nu exista potrivire cu string2 in string1
string last string1 string2
Inapoiaza index-ul elementului din string1 care incepe ultima procedura cu string2 sau -1 daca nu exista potrivire cu string2 in string1
string wordend string index
Inapoiaza index-ul unui caracter exact dupa ultimul din cuvant care contine elementul index al unui sir.Un cuvant este oricare set contiguu de litere, numere sau elemente subliniate sau oricare alt element unic.
string wordstart string index
Inapoiaza index-ul unui caracter exact dupa primul din cuvant care contine elementul index al unui sir.Un cuvant este oricare set contiguu de litere, numere sau elemente subliniate sau oricare alt element unic.
string match pattern string
Devine 1 daca pattern se potriveste cu string. Pattern este un model in stil sferic.
Globbing este technica wildcard folosita de shell.
globbing wildcards sunt:
Potriveste orice cantitate a oricarui element
Potriveste orice intamplare a oricarui caracter
X Backslash-ul trece cu vederea un caracter special la fel cum o face si in substitutiile tcl. Folosirea backslash-ul permite folosirea sferei pentru a potrivi un * sau ?.
Gaseste orice intamplare a oricarui element situat intre paranteze. Un rand de caractere poate fi potrivit folosind un sir dintre paranteze. De exemplu: [a-z] se va potrivi cu orice litera dintr-o grupa mai mica.
Acestea sunt comenzile care modifica un rand. A se retine ca nici una dintre acestea nu modifica locul randului. In toate cazurile,un nou rand va rezulta.
tolower string
Rezulta un sir cu toate literele convertite de la partea de sus la cea de jos.
toupper string
Razulta un sir cu toate literele convertite de la partea de jos la cea de sus.
trim string ?trimChars?
Rezulta un sir cu toate intamplarile trimChars indepartate de la ambele capete. Prin scadere trimChars sunt spatii goale (spaces, tabs, newlines)
trimleft string ?trimChars?
Rezulta un sir cu toate intamplarile din trimChars mutate din stanga. Prin scadere trimChars sunt spatii goale (spaces, tabs, newlines)
trimright string ?trimChars?
Rezulta un sir cu toate intamplarile din trimChars mutate din dreapta. Prin scadere trimChars sunt spatii goale (spaces, tabs, newlines)
format formatString ?arg1 arg2 argN?
Rezulta un sir formatat in aceeasi maniera ca si procedura ANSI sprintf. FormatString este o descriere a formatarii de folosit. Definitia intreaga a acestuiu protocol este in pagina format man. Un subset folositor al definitiei este acela ca formatString este alcatuita din cuvinte de tipar, secvente de backslash si campuri% . Campurile % sunt siruri care incep cu % si se termina cu una dintre urmatoarele :
s Data este un sir
d Data este o integrala decimala
x Data este o integrala hexadecimala
o Data este o integrata octala
f Data este numar variabil
% poate fi urmat de
. Stanga justifica data din acest camp
Dreapta justifica data din acest camp
Valoarea de justificare poate fi urmata de un numar dand numarul minim de spatii de folosit pentru data
Expresii regulate 101
Tcl mai suporta si operatiile cu siruri cunoscute ca regular expressions. Cateva comenzi pot accesa aceste metode prinntr-un argument -regexp, a se vedea paginile man pentru care comenzile sustin expresii reglate.
There are also two explicit commands for parsing regular expressions. De asemenea mai exista si doua comenzi clare pentru analizarea expresiilor aranjate.
regexp ?switches? exp string ?matchVar? ?subMatch1 subMatchN?
Cauta in sir expresia reglata exp. Daca este dat un parametru matchVar, atunci subsirul care se potriveste cu expresia reglata este copiat in matchVar. Daca exista variabile subMatchN, atunci partile parantetice ale sirului gasit care sunt copiate variabilelor subMatch, lucrand de la dreapta la.
regsub ?switches? exp string subSpec varName
Cauta in sir subsiruri care se potrivesc cu expresia reglata exp si o inlocuieste cu subpec. Sirul rezultat ste copia in varName.
Expresiile reglate pot fi exprimarte doar cu cateva reguli
se potriveste cu inceputul unui sir
se potriveste cu sfarsitul sirului
se potriveste cu orice element unic
se potriveste cu orice numarare (0-n) a elementului anterior
se potriveste cu orice numarare, but dar macar 1 din elementele anterioare
se potriveste oricarui caracter al unui set de caractere
Se potriveste cu orice element care nu este membru al setului de caractere ce ii urmeaza lui ^
Grupuri de seturi de elemente dintr-un subpec.
Expresiile reglate sunt similare cu globbing-ul care a fost prezentat in lectiile 16 si 18. Principala diferenta este modul in care seturile de caractere asemanatoare sunt In globbing singura modalitate de a selecta seturi de text necunoscut este simbolul *. Aceasta se potriveste cu orice cantitate a oricarui element.
In analizarea expresiilor regulate, simbolul * se potriveste cu 0 sau mai multe intamplari ale elementului precedand imendiat . Spre exemplu a se va potrivi cu a, aaaaa sau un sir gol. Daca elementul chiar dinaintea lui * este un set de elemente aflate intre paranteze drepte, atunci * se va potrivii cantitatii tuturor acestor elemenete. De exemplu, [a-} se va potrivi cu aa, abc, aabcabc sau iar, cu un sir gol.
The + symbol behaves roughly the same as the *, except that it requires at least one character to match. For example, [a-c]+ would match a, abc, or aabcabc, but not an empty string. Simbolul + se comporta sumar ca si *, exceptand faptul ca are nevoie de macar un element asemanator. De exemplu, [a-c] se va potrivi cu a, abc sau aabcabc, dar nu si cu un sir gol.
Analizarea expresiilor reglate este mult mai puternica decat globbing. Cu globbing poti folosi paranteze patrate pentru a inchide un set de elemente dintre care vor fi o potrivire. Analizarea expresiilor reglate include si o metoda de selectare a unui element ce nu se afla in set. Daca primul element dupa [ este simbolul (^), atunci analiza expresiei se va potrivi cu oricare element care nu se afla in setul de caractere dintr parantezele drepte. (^) poate fi inclus in setul de elemente care se potrivesc (sau nu) prin plasarea lui in oricare alta pozitie decat prima.
Comanda regexp este similara comenzii strig meci in faptul ca potriveste un exp de un sir. Este diferita pentru ca poate potrivi o portiune din sir in loc de tot sirul si va pozitiona caracterele gasite intr-o variabila matchVar.
Daca este gasita o asemanare portiunii expresieri reglate aflate intre paranteze, regexp va copia subsetul de caractere asemanatoare in argumentul subSpec. Asta poate fi folosita pentru a analiza siruri simple.
Regsub va copia unei noi variabile continutul sirului, substituind elementele care se potrivesc cu exp cu elementele din subSpec. Daca subSpec contine un & sau 0, atunci acelste elemente vor fi inlocuite cu elementele care s-au potrivit cu exp. Daca numarul ce urmeaza unui backslash este 1-9, atunci secventa backslash va fi inlocuita cu o portiune convenabila a exp care este inchisa intre paranteze.
A se observa ca argumentul exp to regexp or regsub este procesat de pass-ul de substituire al Tcl. Asa ca destul de des expresia este pusa intre acolade pentru a preveni orice procesare speciala facuta de Tcl.
MAI MULTE EXEMPLE DE EXPRESII REGULATE
Expresiile regulate furnizeaza o metoda puternica in definirea modelului, dar ele sunt un pik neindemanatice la intelegere si in folosinta propiu-zisa. Asa ca haideti sa examinam cateva exemple in detalii.
Vom incepe inca cu un simplu exemplu non-trivial: gasimt floating-points intr-o linie a textului. Nu va faceti griji vom tine problema simpla decat este in plina generalitate.vom considera numere numai 1.0 si nu 1.00e + 01.
Cum vom studia expresiile noastre regulate in aceasta problema? Examinand exemple caracteristice cu stringuri care vrem sa se potriveasca:
Numere valide :
Numere invalide:
Numere discutabile:
Le vom accepta - pentru ca ele sunt acceptate normal si pentru ca excluderea lor face modelul nostru sa fie mai complicat.
Un model incepe sa apara:
Un numar poate incepe cu un semn (+ sau -) sau cu numar. Acesta poate fi capturat cu o expresie [-+] ? , care se potriveste unic "-", si un unic "+" sau nimic.
Un numar poate poate avea zero
si mai multe unitati in fata perioadei (.) si poate avea zero si alte unitati
dupa perioada. Probabil [0-9]*.[0-9]* va face .
Un numar poate sa nu contina o
perioada deloc. Revedeti expresia precedenta: [0-9]*.?[0-9]*
Expresia totala este:
[-+]?[0-9]*.?[0-9]*
In momentul acesta putem face trei lucruri:
1. Vom incerca expresia cu mai multe exemple precum cele de mai sus si sa vedem daca cea adecvata se potriveste si care nu.
2. Incercam sa sa arate cat mai bine, inainte de testare. Ca exemplu clasa de caratere "[0-9]" este asa de cunoscuta incat are si o scurtatura "d". Deci, am putea so aranjam asa:
in loc. Sau am putea decide ca vrem sa capturam unitatile inainte sau dupa perioada pentru un proces mai special:
3. Este o strategie buna in generalputem sa examinam modeulul cu mare atentie inainte de a il folosi.
Vedeti este o problema cu modelul de deasupra: toate partile sunt optionale, asta inseamna ca fiecare parte se poate potrivi cu un string nul - nici un semn , nici o unitate inainte de perioada, nici o perioada, nici o unitate dupa perioada. In alte cuvinte: Modelul nostru se potriveste cu un string gol!
Numere discutabile ca "+000" vor fi perfect acceptate si noi (in sila)le vom accepta. Dar mai surprinzator sunt stringurile "--1" si "A1B2" vor fi acceptate si ele. De ce? Pentru ca modelul incepe cu un string, si se poate potrivi cu substringurile "-1" si respectiv "1".
Trebuie sa reconsideram modelul nostru - este prea simplu si prea permitator:
Caracterul din fata minusului sau a plusului, daca sunt, numai poate fi inca o cifra, o perioada un minus sau un plus. Sa facem un spatiu un salt sau inceputul unui string: ^ | [ t ]: s-ar putea sa vi se para un pic ciudat dar ceea ce scrie acolo este: fiecare inceput de string ( ^ in afara parantezelor patrate ) sau ( bara verticala ) un spatiu sau un salt ( retineti: "t" reprezinta caracterul care face salt ).
Orice secventa a unei cifre inaintea perioadei ( in caz de este una ), este permis: [0-9]+.?
S-ar putea intampla ca sa fie zero cifre in fata perioadei, dar dupa aia va trebui sa aiba cel putin una dupa perioada: .[0-9]+
Si normal cifre in fata sau in spatele perioadei: [0-9]+ . [0-9]+
Caracterul dupa string ( in caz de este ) nu poate fi "." , "-" sau "+" pentru ca ne-ar baga intr-un numar neacceptabil $ | [ + - . ] ( Semnul dolarului semnifica sfarsitul stringului ).
Inainte de a scrie expresia regulata completa, sa vedem ce forme diferite avem:
Nu avem perioada: [-+]?[0-9]+
O perioada fara cifre inaintea ei: [-+]?.[0-9]+
Cifre inaintea perioadei, si posibil dupa: [-+]?[0-9]+.[0-9]*
Si acum sinteza:
sau
Este nevoie de paranteze pentru a putea deosebi alternativele introduse de bara verticala si capturarea unui substring pe care il vrem sa-l avem. Fiecare set de paranteze defineste de asemenea un substring si acesta poate fi pus intr-o variabila separata.
Nota: pentru a identifica un substring, numarati parantezele deschise de la stanga la dreapta.
Daca il punem la un test:
rezultatul este:
Deci modelul nostru accepta corect stringurile menite pentru a fi recunoscute ca numere si ca respengerea altora.
Hai sa ne intoarcem la alte modele acum:
Textul cuprins intr-un string: Acesta este un "text citat". Daca stim ingradirea caracterului in avantaj (ghilimele , " in acest caz), apoi " ( [ ^ " ] ) * " va cuprinde textul in interiorul ghilimelelor.
Sa presupunem ca nu stim ingradirea unui character ( poate fi " sau ' ). Apoi:
il va face: - acest 1 este asa-numit raport-sprijin la primul substring capturat.
Puteti sa folositi tehnica asta pentru a vedea daca un cuvant se aplica de doua ori in aceiasi linie:
( Modelul y se potriveste la inceputul sau sfarsitul unui cuvant si w+ indica ca vrem cel putin un caracter ).
Sa presupunem ca trebuie sa verificam parantezele cu expresii matematicale: (1+a)/(1-b*x) de exemplu. O simgura verificare numara toate parantezele deschise sau inchise.
Bineinteles, aceasta este doar o verificare ordinara. Una mai buna este sa vedem daca la fiecare punct cat timp scaneaza stringul acolo sunt mai multe paranteze inchise decat paranteze deschise. Putem foarte simplu sa extragem parantezele si sa le punem intr-o lista ( optiunea inline face asta ).
Final: expresiile regulate sunt foarte puternice, dare le au o anumita limita teoretica. Una din aceste limite este aceea ca ele nu sunt potrivite pentru analiza arbitrara nested text.
More Quoting Hell - Regular Expressions 102
regexp ?switches? exp string ?matchVar?
?subMatch1 subMatchN?
Cauta stringul pt expresia regulata exp.Daca este dat un parametru <matchVar>, atunci substringul care se portriveste expresiei regulate,este copiata in <matchVar>. Daca exista variabile <subMatchN> ,atunci partile din paranteze ale stringului pereche sunt copiate in variabilele <subMatch> lucrand de la stanga la dreapta.
regsub ?switches? exp string subSpec
varName
Cauta string pt substringul care se potriveste expresiei regulate exp si le inlocuieste cu subSpec.Stringul rezultat este copiat in varName.
Expresia regulata (exp) din a doua expresie analizand comenzile este evaluata de analizatorul Tcl in timpul fazei de substitutie Tcl. Acest lucru poate furniza multa putere dar in acelasi timp necesita o mare atentie.
Aceste exemple dezvaluie unele din cele mai inselatoare aspecte ale evaluarii expresiei regulate.Domeniile din fiecare exemplu sunt discutate in detaliu amanuntit si la cel mai complicat nivel.
Punctele de care trebuie tinut cont in timp ce citesti exemplele sunt :
* Paranteza patrata deschisa ( [ ) are rol in faza de substitutie si in analizarea expresiei regulate.
* O pereche de paranteze , semnul plus si stelutza au rol in analizarea expresiei regulate dar nu si in faza de substitutie Tcl.
* Secventa backslash (n,t, etc) are rol in faza de substitutie Tcl ,dar nu si in analizarea expresiei regulate.
* Caracterul backslash ([) nu are nici o semnificatie atat pentru faza de substitutie Tcl cat si pt analiza expresiei regulate.
Faza in care un caracter are influente semnificative,multe pauze sunt necesare pt a potrivi caracterul dorit. O pauza ar putea ori inchide expresia in acolade, ori ar putea pune un backslash inaintea caracterului eliminat.
Pentru a trece paranteza stanga in analizarea expresiei regulate pt a fi evaluata la rangul de caracter necesita 1 pauza. Pentru ca analiza unei expresii regulate sa se potriveasca literal in stanga parantezei trebuie doua pauze(una in faza de substitutie Tcl si una in analiza expresiei regulate). Daca stringul este plasat intre ghilimele atunci un backslash pasat analizei regulate trebuie deasemenea eliminat cu un backslash.
Limbaje precum C,BASIC,FORTRAIN si Java sustin arrays in care valoarea indexului este o integer.Tcl,precum majoritatea limbajelor de scripiting (Perl ,Python,PHP,etc)sustin arrays asociabile (cunoscute si ca 'hash tables')
in care valoarea indexului este un string.
Sintaxa pt arrays asociabile este punerea indexului intre paranteze.
array exists arrayName Returneaza 1 daca arrayName este o variabila array.Returneaza 0 daca arrayName este o variabila scalara,procedura,ori nu exista.
array names arrayName?pattern. Returneaza o lista de indici pentru array asociative arrayName. Daca pattern este furnizat atunci doar acei indici care se potrivesc pattern sunt returnate. Perechea este facuta folosind tehnica globala a perechii stringului.
array size arrayName. Returneaza numarul de elemente din arrayName.
array get arrayName. Returneaza o lista in care fiecare element ciudat/in plus este un index in arrayul asociat.Lista de elemente, urmarind un nume/o mentionare ,este valoarea acelui membru array.
array set arrayName datalist. Transforma o lista intr-un array asociativ. DataList este o lista in formatul a ceea ce returneaza array get.Fiecare element ciudat/in plus este un index pentru arrayul asociat, iar lista de elemente, ce urmeaza asta,este valoarea acelui membru array.
Cand un nume array asociativ este dat ca un argument pt comanda globala,toate elementele acelui array asociativ devin disponibile acelei proceduri.Din acest motiv, Brent Welch recomanda (in programarea reala Tcl si Tk) folosirea unui array asociativ pentru o categorie,structurat intr-un pachet.
Alta folosire obisnuita pt arrays este stocarea datelor in tabel.In exemplul de mai jos folosim un array pt simpla stocare a unei baze de date cu nume.
More Array Commands - Iterating and use in procedures
Deseori vezi vrea sa buclati prin continutul unu asociativ array - fara a specifica elementele explicite. Pentru aceste array names si array get comenzile sunt foarte utile. Cu amandoua poti da un (glob-style) model pentru a selecta ce elemente ai nevoie:
Nota, oricum, elementele nu vor fi returnate intr-o oridine previzibila: aceasta are de a face cu sublinierea "Hash table". Daca vrei o orine particulara (alfabetica de exemplu) poti folosi acest cod:
Cat timp array-urile sunt bune pentru facilitatea inmagazinata pentru cateva scopuri, ele sunt un pic inselatoare cand vrei sa treci cu ele la o procedura: ele sunt defapt colectii ale variabilelor. Aceasta nu va merge:
Motivul este simplu: un array nu are valoare. In schimb codul de mai sus ar trebui sa fie:
Deci, in loc sa trecem o "valoare" pentru un array, vei trece name. Aceasta primeste numele (via comanda upvar ) la o variabila locala (care se poarta ca un array original). Poti face schimbi in array-ul original in aceasta forma.
File access 101
Tcl furnizeaza cateva metode de citie si scriere aflate pe disk. Cea mai simpla metoda de a accesa un fisier este via gets si puts. Cand sunt multe date de citit, oricum, cateodata este mai eficient sa folositi comanda read pentru a incarca intregul fisier, si pentru a aniliza fisierul pe linii folositi comanda split.
Aceste metode pot fi folosite si in comunicarea peste sockets sau peste pipes. Este chiar posibil , via asa-zise-i virtual file system pentru a folosi fisiere stocate in memorie decat cele de pe disk. Tcl furnizeaza o interfata uniforma la aceste resurse diferite, deci in general nu trebuie sa te ingrijorezi cu detalii.
open fileName ?access? ?permission?
Deschide un fisier si returneaza un indiciu ca sa
fie folosit cand este acceseaza un fisier via gets, puts, close,
etc.
FileName este numele fisierului care trebuie deschis.
access este modul de acces al fisierului.
o rDeschide fisierul pentru citire. Fisierul trebuie sa existe.
o r+.Deschide fisierul pentru citire si scriere. Fisierul trebuie sa existe.
o wDeschide fisierul pentru scriere. Creati fisierul daca nu exista, sau setati lungimea la zero in caz de nu exista.
o w+.Deschide fisierul pentru scriere si citire. Creati fisierul daca nu exista, sau setati lungimea la zero in caz de nu exista.
o a..Deschide fisierul pentru scriere. Fisierul trebuie sa existe. Setati locatia curenta la sfarsitul fisierului.
o a+Deschide fisierul pentru scriere. Daca fisierul nu exista creati-l. Setati locatia curenta la sfarsitul fisierului.
permission este un interger folosit sa seteze pemisiunea la fiserul acces. Lispa rw-rw-rw- (0666). Puteti sa-l folositi in setarea unui fisier al proprietarului, grupul el/ea apartine tuturor celorlati useri. Pentru mai multe aplicatii absenata este buna.
Comanda source va incarca un fisier si il va executa. Asta perimte unui program sa fie impartit in mai multe fisiere cu fiecare procedura de clarificare a fisierelor si variabile pentru o anumita arie de functionalitate. Spre exemplu, se poate avea un fisier numit database.tcl care sa se contina toate procedurile pentru a avea de aface cu o baza de date sau cu un fisier numit gui.tcl care se ocupa cu creearea unei interfate grafice a userului cu tk. Scriptul principal poate pur si simplu sa includa fiecare fisier folosind comanda source. Tehnici mult mai puternice pentru modularizarea programului sunt aduse in discutie in urmatoarea lectie despre pachete.
Comanda poate fi folosita ca sa:
Separe un program in fisiere multiple.
Sa creeze un fisier care sa contina tooate procs-urile pentru un anumit set de functii.
Sa configureze programe.
Sa incarce fisiere data.
source fileName
Citeste scriptul din filename si il executa. Daca scriptul executa cu succes, source inapoiaza valoarea ultimulei expuneri din script.
Daca exista vreo greseala in script, source va arata acea eroare.
Daca exista o intoarcere (in afara de aceea din definitia proc) atunci source se va intoarce imediat, fara sa execute restul scriptului.
Daca filename incepe cu o tilda (~) atunci $env(HOME) va fi substitut pentru acea tilda ca si in comanda file.
sourcedata.tcl:
sourcemain.tcl:
O diferenta dintre Tcl si majoritatea adunatorilor este ca Tcl va da voie unui program executant sa creeze noi comenzi si le execute in timpul rularii.
O comanda tcl este definita ca fiind o lista de siruri in care primul sir este o comanda sau un proc. Orice sir sau lista care indeplineste acest criteriu poate sa fie evaluat si executat.
Comanda eval va evalua o lista de siruri ca si cand ar fi comenzi scrise la prompt-ul % sau cu sursa intr-un fisier. In mod normal comanda eval va rezulta valoarea finala a comenzii aflata in evaluare. Daca, comenzile de evaluat dau o eroare (de exemplu, daca exista o eroare de sintaxa intr-unul din siruri), atunci eval va da o eroare.
A se nota ca oricare: concat sau list pot fi folosite la creearea sirului de comanda,dar aceste doua comenzi vor creea siruri de comanda putin mai diferite.
eval arg1 ??arg2?? ??argn??
Evalueaza arg1 - argn ca una sau mai multe comenzi Tcl. The args sunt inlantuite intr-un sir si trecute la tcl_Eval pentru evaluare si executie.
Eval returneaza rezultatul (sau codul de eroare) evaluarii.
More command construction - format, list
Ar putea exista cateva rezultate neasteptate cand se incearca o creeare a sirurilor de comanda pentru eval
De exemplu:
eval puts OK
va printa sirul OK. totusi,
eval puts Not OK
va genera o eroare.
Motivul pentru care a doua comanda genereaza o eroare este acela ca eval foloseste concat pentru a-si imbina argumentele intr-un sir de comanda. Aceasta cauzeaza ca cele doua cuvinte NOT OK sa fie tratate ca doua argumente la puts. Daca exista mai mult de un argument la puts, primul argument trebuie sa fie un indicator de fisiere.
Moduri corecte de a scrie a doua comanda sunt acestea:
eval [list puts ]
eval [list puts 'Not OK']
set cmd 'puts' ; lappend cmd ; eval $cmd
Atata timp cat se inregistreaza cum sunt grupate argumentele prezentate lui eval, se pot cauza multe metode de formare a sirurilor pentru eval, incluzand comanda string si fornat.
Metodele recomandate de a construi comenzi pentru eval sunt de a folosi comenzile list si lappend. Aceste comenzi devin dificil de folosit daca trebuie folosite paranteze drepte in comanda, asa cum a fost facut in lectia anterioara.
Exemplul de la lectia anterioara este re-implementat in codul exemplu, folosind lappend.
Intregimea unei comenzi poate fi verificata cu info complete. Info complete poate fi folosit si intr-un program interactiv care sa determine daca linia tastata este o comanda completa sau doar introdusa de user pentru a forma comanda mai bine.
info complete string
Daca string nu are paranteze asemanatoare,acolade sau paranteze drepte atunci valoarea lui 1 este returnata,altfel rezulta 0.
Tcl sustine si comenzi care schimba si arata directorul in care se lucreaza in acel moment.
Acestea sunt:
cd ?dirName?
. Schimba directorul curent in dirName (daca dirName este dat sau directorului $HOME daca dirName nu este dat). Daca dirname este o tilda (~, cd schimba directorul de lucru cu directorul home al userilor. Daca dirname incepe cu o tilda, atunci restul elementelor sunt tratate ca un id de logat si cd schimba directorul in care se lucreaza cu $HOME al userului.
pwd
Reface directorul curent.
More Debugging - trace
Cand se deviruseaza un program. Este cateodata util sa se stie cand o variabila se schimba. Interpretul Tcl sustine o metoda pentru a urmari cand si cum o variabila este accesata. Cu comanda trace o porcedura poate fi definita pentru fi executata oricand este citita,scrisa nesetata o variabila.Cu aceasta comanda se poate determina proc-ul modificarea unei variabile, in ce a fost schimbata valoarea si ce variabile au fost in timpul ala.
Comanda trace executa la acelasi nivel al grupului asa cum o face si accesul variabilei. Proc-ul invocat de trace se afla cu un nivel mai jos. Altfel cu comanda uplevel o procedura chemata prin trace poate raporta conditiile puse cand a fost accesata o variabila.
trace variable variableName operation procname
Plaseaza o investigatie asupra variabilei lui variableName. Cand o variablename este accesata pentru operatiunea specificata in operatia argument, procedura procname va fi adusa in discutie.
Operatiunea este una de :
r Citit
w . Scris
u Nesetat
O variabila poate fi nesetata ori explicit cu comanda unset ori implicit cand o procedura se intoarce si taoite variabilele locale sunt eliberate.
Cand este accesat variableName, procname va fi numit cu trei argumente: variableName, elementName si operation. Daca variabila accesata este aranjata asociativ atunc elementName va contine numele elementului accesat. Daca variableName este o simpla variabila, atunci elementName va fi un sir gol. Operation este operatia care a fost facuta pe variablename ca sa fie invocata actiunea trace.
trace vdelete variableName operation procname
Anuleaza actiunea de gasire pentru operarea pe variableName.
trace vinfo variableName
Reface informatia despre urmele aplicate lui variableName.
Scripturile sunt mult mai utile daca pot fi denumite cu valori diferite in linia de comanda.
De exemplu, un script care extrage o valoare speciala dintr-un dosar poate fi scris astfel incat sa caute, sa citeasca numele documentului si sa extraga datele. Sau poate fi scris ca sa treaca printre atatea fisiere cate sunt in linia de comanda si sa extraga datele din fiecare si sa printeze data si numele fisierului.
A doua metoda de a scrie programul poate fi foarte usor folosita de la alte scripturi. Asta face totul mai util.
Numarul argumentelor comenzilor de sir ale unui script Tcl este trecut ca fiind variabila globala argc. Numele unui script Tcl este dat scriptului ca variabila globala argv0 si restul argumentelor comenzilor de sir sunt trecute ca o lista in argv.
Alta metoda de a trece informatiile printr-un script este cu ajutorul variabilelor de imprejurimi. De exemplu, a se presupune scrierea unui program in care userul prevede un fel de comentariu pentru a fi inregistrat. Ar fi bine sa se permita userului sa editeze comentraiile lor in editorul preferat. Daca userul a specificat un editor variabil la imprejurimi, atunci se poate invoca editorul pe care il pot folosi.
Sub supusele sisteme de operare Posix, variabilele de imprejurari sunt trecute intr-un script Tcl intr-o ordine env global asociativa. Indicele din env este numele variabilei imprejurimilor. Comanda puts '$env(PATH)' va printa continutul variabilei de imprejurimi PATH.
Cea mai simpla metoda de a face un script sa mearga mai repede este de a cumpara un procesor mai rapind. Din pacate. Asta nu este intotdeauna o optiune. Poate sa fie necesara optimizarea scriptului pentru a merge mai repede. Asta este dificil daca nu se poate masura timpul cat dureaza sa ruleze portiunea scriptului care se doreste optimizat.
Comanda time este solutia la aceasta problema. Time va masura cat dureaza executarea unui script. Apoi se poate modifica scriptul, reporni si observa cat a fost imbunatatit.
Mai poate fi necesar sa se optimizeze memoria folosita de script sau sa se curete variabile dupa fiecare trecere printr-un loop. Comanda unset va sterge o variabila din locul unde trebuie sa fie numele interpretului.
Dupa ce a fost rulat exemplul, jucati-va cu marimea contrapartidelor rutei in timetst1 si timetst2. Daca contrapartida interioara este 5 sau mai putin, poate dura mai mult executarea lui timetst2 decat a lui timest1. Asta pentru ca ia mai mult timp sa se calculeze si sa se repartizeze variabila k si daca loop-ul interior este prea mic, atunci castigul in a nu face inmultirea in interiorul loop-ului este pierduta in timpul care ia sa se calculeze loop-ul extern.
time script ?count?
Rezulta cate milisecunde a durat sa execute scriptul. Daca count este specificat, atunci va porni script count times si va rezulta media. Timpul este timpul trecut,nu timpul CPU.
unset variableName1 ?variableName2 ?
Sterge variableName din spatiul numelui interpretului. daca variableName este un nume aranjat, atunci intregul aranjament va fi sters. Daca variableName este un element dintrun aranjament, atunci numai acelasi element va fi sters. If any of the variables to delete do not exist, then unset will return an error, and any variables after the non-existent variable will not be deleted.
Channel I/O: socket, fileevent, vwait
Tcl I/O se bazeaza pe un canal. Un canal este conceptual asemanator lui FILE * in C sau un val in programarea unui shell. Diferenta este ca un canal poate fi ori un mijloc de curent ca un document, un tape drive sau tty sau o conexiune orientata construita ca un port.
Un canal baza pe un sir este format prin comanda open,asa cum a fost discutat si in lectia 26. Un canal bazat pe porturi este format printr-o comanda socket. Un port poate fi deschis fie ca un client TCO sau ca un server.
Daca un canal este deschis ca un server, atunci programul tcl va "urmari" pe acelasi canal o alta sarcina in incercarea de a se conecta cu ea. Cand asta se intampla, un nou canal este creeat pentru linku-ul acela (server-> new client) si programul tcl continua sa urmareasca legaturi pe numarul original al portului. In acest mod, un server unic Tcl ar putea interactiona cu mai multi cilenti.
Cand exista un canal,un handler poate fi definitivat cand va fi invocat atunci cand canalul este liber pentru citit sau scris. Acest handler este definit cu ajutorul comenzii fileevent. Cand o procedura tcl indeplineste gets sau puts unui procedeu de bloca si procedeul nu este pregatit pentru I/O, programul va fi blocat pana este gata planul. Ar putea dura mult pana cand celalalt sfarsit al canalului I/O trece offline. Folosind comanda fileevent, programul poate accesa numai canalul I/O cand este gata sa mute date.
In sfarsit, exista o comanda ca sa astepte pana se intampla un eveniment. Comanda vwair va astepta pana este setata o variabila. Aceasta poate fi folosita pentru a crea un stil functional semnalant pentru interactiunea dintre client si server si sa anunte procedura dominanta ca a avut loc un eveniment.
A se observa exemplul:comanda socket este folosita ca si client si server si comenzile fileevent si vwait folosite de catre client si server pentru a controlaI/O dintre client si server.
A se nota ca in particular comenzile flush sunt folosite. Ca si un canal care este deschis ca un conductor la comanda nu se trimit date decat atunci cand un flush este invocat sau este umplut un amortizor, canalele bazate pe porturi nu trimit automat date.
socket -server command ?options? port
Comanda socket impreuna cu -server flah deschid o conexiune pe server sau un port. Cand o conexiune se intampla la port, comanda proc este chemata cu argumente:
channel . . . .Canalul pentru clientul nou
address . . . . Adresa de IP a acestiu client
port. . . . . . . . Portul dat clientului
socket ?options? host port
Comanda socket fara optiunea -server deschide o conexiune clinet sistemului cu adresa de IP host si cu adresa portului port. Adresa Ip-ului poate fi data ca un sir numeric sau ca o adresa calificata de domeniu.
Pentru conectarea la host trebuie folosita adresa 127.0.0.1 (adresa loopback).
fileevent channelId readable ?script?
fileevent channelId writeable ?script?
comanda fileevent defineste o invocare a unui handler atunci cand are loc un eveniment care invoca scriptul cand o data este pregatita a fi citita pe un channelId si writeable cand channelID este pregatit sa primeasca date.
vwait varName
Comanda vwait opreste executia scriptului pana cand actiunea de fundal seteaza valoarea lui vartName.O actiun de fundal poate fi un proc invocat printr-o fileevent sau o conexiune priza sau un eveniment de la un widget tk.
Comanda clock prevede acces functiilor datelor si timpului in Tcl. In functie de subcomenzile invocate poate sa procure ora curenta sau sa se converteasca intre diferite reprezentari de timp si data.
Comanda clock este o metoda platforma independenta de a procura expunerea functionalitatii comenzii unix date si de a procura acces valorilor rezulate de o accesare gettime unix
clock seconds
Comanda clock seconds da timpul in secunde de cand a inceput epoca. Data epocii variaza pentru diferitele sisteme de operare astfel incat valoarea este importanta pentru scopuri de comparare sau ca input pentru comanda clock format.
clock format clockValue ?-gmt boolean? ?-format string?
Subcomanda format formeaza clockvalue(asa cum este rezultat de clock clicks intr-un sir uman lizibi)l.
Ca un argument secund, intrerupatorul -gmt foloseste boolean. Daca boolean este 1 sau Adevarat, atunci timpul va fi format dupa Greenwich Mean Time, in alt caz va fi format ca timp local.
Optiunea -format controleaza in ce format va fi rezultatul.Continutul unui argument string la format are continutul asemanator ca si expunerea format(asa cum a fost discutat in lectiile 19,33.34).In plus mai exista mai multi descriptori % care pot fi utilizati pentru a descrie output-ul.
Acestea includ:
%a . . . . Numele abreviat al unei zile(Mon, Tue, etc.)
%A . . . . Numele complet al unei zile (Monday, Tuesday, etc.)
%b . . . . Numele abreviat al lunii (Jan, Feb, etc.)
%B . . . . Numele complet al lunii (January, February, etc.)
%d. . . . . O zi a lunii
%j . . . . . Julian day of year
%m . . . . Numarul lunii (01-12)
%y. . . . . Anul din secol
%Y . . . . An cu 4 cifre
%H . . . . Ora (00-23)
%I . . . . . Ora (00-12)
%M . . . . Minute (00-59)
%S . . . . . Secunde(00-59)
%p . . . . . PM sau AM
%D . . . . Data ca %m/%d/%y
%r. . . . . Ora ca %I:%M:%S %p
%R . . . . Time as %I:%M
%T . . . . Time as %I:%M:%S
%Z . . . . Time Zone Name
clock scan dateString
Subcomanda scan schimba un sir uman lizibil intr-o valoare al ceasului de sistem si ar fi returnat de clock seconds.
Argumentul dateString contine siruri in aceste forme:
time
O perioada de zi intr-unul din formatele de mai jos. Meridian poate fi AM sau PM sau o varianta de capitulare. Daca nu este specificat atunci ora (hh)este interpretata ca un ceas de 24 de ore. Zona poate fi o descriere e trei litere a unei zone de timp,EST,PDT, etc.
hh:mm:ss ?meridian? ?zone?
hhmm ?meridian? ?zone?
date
O data apare ca in in exemplele de mai jos.
mm/dd/yy
mm/dd
monthname dd, yy
monthname dd
dd monthname yy
dd monthname
day, dd monthname yy
Lectiile anterioare au aratat cum se utilizeaza canale cu documente si blocari de prize. Tcl mai sustine si citiri si scrieri care antiblocare si permite coinfigurarea marimilor amortizoarelor I/O si cum sunt terminate sirurile.
O citire sau o scriere anti-blocare inseamna ca in loc de o chemare gets in asteptare pana cand data este valabila se va intoarce imediat. Daca ar fi informatii valabile,vor fi citite,daca nici o data nu este valabila chemarea gets va rezulta o lungime 0.
Daca exista canale care trebuie verificate pentru input, se poate folosi comanda fileevent pentru a impiedica citiri pe canal si apoi sa se utilizeze comanda fblocked pentru a determina cand sunt citite toate informatiile.
Comenzile fblocked si configure dau mai control asupa comportamentului unui canal.
Comanda fblocked verifica daca un canal a rezultat toate input-urile valabile. Este util atunci cand se lucreaza cu un canal care a fost setat la un mod de non-blocare si este nevoie sa se determine daca exista informatii valabile sau daca un canal a fost inchis din partea cealalta.
Comanda fconfigure are multe optiuni care permit sa se chestioneze sau sa se acorde comportamentul unui canal, incluzand si daca acesta blocheaza sau nu,marimea amortizorului si sfarsitul elementului linie.
fconfigure channel ?param1? ?value1? ?param2? ?value2?
Configureaza comportamentul unui canal. Daca nici o valoare param esre data, o lista a parametrilor valizi configurati si valorile lor e returnata.
Daca este dat numai un singur parametru pe linia de comanda, valoarea parametrului este returnata.
Daca sunt date una sau mai multe perechi de param/value,acei parametrii sunt setati la valoarea ceruta.
Parametrii care pot fi setati include:
-blocking . . . Determina daca atunci cand informatia nu poate fi mutata pe un canal,comanda va bloca.(i.e. daca nu este valabila nici o informatie la o citire sau daca amortizorul este plin la scriere).
-buffersize . . . Numarul bitilor care vor fi amortizati inainte de trimiterea informatiei sau inainte de a fi citita atunci cand este primita. Valoarea trebuie sa fie un numar intreg intre 10 si 1000000.
Seteaza cum Tcl va termina o linie cand este produsa. Prin scadere, liniile sunt sterse cu o linie noua, rezultatul transportului sau un sir nou/transport rezultat care este specific sistemului in care ruleaza interpretul.
Asta poate fi configurat sa fie:
o auto . . . Trateaza linia noua, rezultatul transportului sau un sir nou/transport rezultat ca un sfarsit al unui marcaj. Produce terminatia liniara corecta pentru actuala platforma.
o binary . . Comporta sirurile noi ca sfarsitul marcajelor liniare. Nu adauga nici o terminatie linara sirurilor produse.
o cr . . . .Trateaza rezultatele transportului ca sfarsitul marcajului(si le traduce inter in linii noi).Liniile produse sunt delimitate cu un transport rezultat. Este standardul pentru Macintosh.
o crlf . . . Trateaza perechile cr/lf ca sfarsitul marcajului liniilor si sfarseste liniile produse cu un rezultat al transportului/combinatie linefeed. Este standardul pentru Windows.
o lf . . . . Comporta linefeed-ruile ca sfarsitul marcajului sirurilor si termina producerea liniilor cu un linefeed. Este standardul pentru Unix.
Exemplul este asemanator cu exemplul lectiei 40 cu un client si un port de server in acelasi script. Arata canalul unui server care este configurat sa nu blocheze si care foloseste stilul de amortizare in scadere - data nu este facuta valabila scriptului pana la aparitia unei noi linii sau pana amortizorul nu a completat.
Cand primul scrie: puts -nonewline $sock
'A Test Line'
este
gata, comanda fileevent ingreuneaza citirea,dar gets nu poate citii
caracterele pentru ca nu exista sir nou. Gets rezulta un -1,iar fblocked
un 1. Cand o linie noua este trimisa, informatia din amortizorul input va
deveni valabila si gets rezulta 18,iar fblocked 0.
Child interpreters
Pentru majoritatea aplicatiilor, un singur interpret si subrutine sunt suficiente.Totusi,daca se construieste un sistem cilent-server se poate avea nevoie de mai multi interpreti care sa vorbeasca cu clienti diferiti si sa le mentina starea. Asta se poate face cu variabilele de stare, numind conventii sau schimband satrea la si de la disc,devenind incurcat.
Comanda interp creeaza un nou copilk interpret intr-un interpret deja existent. Copiii interpreti au propriile lor seturi de variabile si documente sau li se poate da acces la unele elemente din interpretul parinte.
Daca este creeat cu comanda -safe, copilul nu va putea accesa documentul de sistem sau sa va strice sistemul. Aceasta caracteristica permite unui script sa evalueze un cod de la un site necunoscut si de neicredere.
Numele copiilor interpreti sunt o lista iererhica. Daca interpretul foo este copilul intrepretului bar,atunci poate fi accesat de interpretul toplevel ca .
Interpretul primar (ceea ce rezulta cand tastati tclsh)este lista goala .
Comanda interp are mai multe subcomenzi si optiuni. Un subset important este:
interp create ?-safe? ?name?
Creeaza un nou interpret si rezulta un nume., Daca optiunea -safe este folosita, noul interpret nu va fi apt sa acceseze anumite facilitati periculoase ale sistemului.
interp delete name
copilul interpret selectat.
interp eval args
Este asemanator unei comenzi eval normale in afara faptului ca evalueaza scriptul in copilul interpret,in loc de interpretul primar.Comanda interp eval concentreaza args-urile intr-un sir si trimite linia respectiva copilului interpret pentru evaluare.
interp alias srcPath srcCmd targetPath targetCmd ?arg arg?
Comanda interp alias permite unui script sa imparta procedurile intre copiii interpreti sau intre un copil si un iterpret primar.
A se nota ca interpretii comandati au un status si namespace separate.dar nu au loop-uri de caz diferite. Acestea nu sunt fire si nu vor executa singure. Daca un interpret subordonat esrte oprit de o cerere de blocare I/O nici un alt interpret nu o va procesa pana nu este deblocata.
Exemplul de mai jos arata creearea a doi copii interpreti cu ajutorul interpretului primar . Fiecaruia dintre acesti interpreti ii este dat un nume variabil care sa contina numele interpretului.
A se observa ca, comanda alias cauzeaza evaluarea procedurii
in interpretul in care procedura a fost definita si nu interpretul in care a
fost evaluata. Daca este necesara existenta procedurii in interpret, atunic o
comanda proc trebuie interp
eval
in interiorul
interpretului. Daca doriti ca interpretul sa fie apt sa recheme interpretul
primar(sau alt interpret)atunci se poate folosi comanda interp alias.