![]() Tcl logo | |
Paradigma | Multiparadigmaticky: imperativní, strukturovany, procedurální, funkcionální, objektově orientovany, ?ízeny událostmi |
---|---|
Vznik | 1988 |
Autor | John Ousterhout |
Vyvojá? | John Ousterhout, Tcl Core Team |
Poslední verze | 8.6.12 (31. ?íjna 2021) |
Poslední nestabilní verze | 9.0a3 (23. ?ervna 2021) |
Typová kontrola | dynamická |
Hlavní implementace | ActiveTcl, Androwish |
Dialekty | Jim |
Ovlivněn jazyky | Awk, Lisp |
Ovlivnil jazyky | PHP,[1] Tea, PowerShell[2] |
Licence | Stylu BSD |
Web | www.tcl.tk |
Tcl (vyslovuje se ?ty-sy-el“ nebo ?tykl“, název je zkratkou z Tool Command Language) je jednoduchy, ale ú?inny skriptovací jazyk, ktery v roce 1988 vytvo?il John Ousterhout. P?es nezvyklou syntaxi je Tcl snadno zvládnutelny a díky nízkym nárok?m na hardware je oblíbeny p?edev?ím pro testování softwaru, programování vestavěnych systém? a prototypování. V roce 1991 byl doplněn grafickym frameworkem Tk a vysledny systém nazyvany Tcl/Tk se stal a? do nástupu Qt a GTK+ jedním z nejoblíbeněj?ích nástroj? pro vytvá?ení grafickych u?ivatelskych rozhraní. Framework Tk je dostupny v r?znych skriptovacích (Perl, Python, Ruby) i kompilovanych jazycích (C++, Ada). Logo jazyka v podobě pírka vychází z anglické slovní h?í?ky, nebo? vyslovnost názvu tykl je stejná jako u slova tickle = lechtat, ?imrat. Pírko (brk) má navíc vyznam coby tradi?ní nástroj dávnych písa?? (prvních skriptér?).
Vlastnosti
[editovat | editovat zdroj]Základní vlastnosti:
- imperativní a procedurální jazyk – program je tvo?en posloupností p?íkaz?
- roz?i?itelnost – u?ivatelem definované procedury se chovají jako vestavěné p?íkazy z knihovny jazyka; lze definovat i p?íkazy slou?ící jako ?ídicí struktury, Tcl lze roz?i?ovat pomocí funkcí v jazyce C, C++ a Java
- extrémně jednoduchá syntaxe – v?echny p?íkazy (i ?ídicí struktury) mají jednotnou strukturu v prefixové notaci (vyrazy ale pou?ívají obvyklou infixovou notaci)
- p?íkazy mohou mít proměnny po?et parametr?
- v?echny p?íkazy mohou byt dynamicky p?edefinovány nebo p?etí?eny
- v?echny datové typy i text programu jsou reprezentovány pomocí textovych ?etězc?, vysledky funkcí lze vkládat p?ímo do textu programu; text programu se dá vytvá?et za běhu
- proměnné mají implicitně oblast platnosti lokální ve funkci, v ní? jsou pou?ity; p?íkazy
uplevel
aupvar
umo?ňují p?ístup k proměnnym z p?edchozích procedur v ?etězci jejich volání; p?íkazglobal
umo?ňuje roz?í?it oblast platnosti na cely zdrojovy soubor - podpora jmennych prostor?
- podpora modulárního programování
- existují objektově orientovaná roz?í?ení
- v?echny p?íkazy definované p?ímo jazykem Tcl generují p?i nesprávném pou?ití chybová hlá?ení
- interpretovany jazyk pou?ívající bytecode
- plná podpora Unicode 3.1 od roku 1999
- p?enositelnost – samotny jazyk, i mnoho knihoven (v?etně Tk) jsou nezávislé na platformě (Windows, Unix, Linux, Mac, Android)
- událostmi ?ízené rozhraní pro sokety a soubory; lze pou?ívat ?asové a u?ivatelem definované události
- úzká integrace s knihovnou grafického u?ivatelského rozhraní Tk
- obtí?ná práce se spojovymi strukturami
Spu?tění Tcl
[editovat | editovat zdroj]Základní interpret jazyka Tcl – tclsh
– lze spustit bez parametr? a s Tcl pracovat interaktivně:
tclsh % expr 22/7 3 % expr 22/7. 3.142857142857143 % expr 4*atan(1) 3.141592653589793 % string length "nejneobhospoda?ovatelněj?ími" 28 % exit
Znak procento (%
) je nápověda, kterou vypisuje interpret Tcl, a která je uváděna pouze u ukázek interaktivní práce. P?íkaz expr
je nutné v Tcl pou?ívat pro vyhodnocování matematickych vyraz?. Lomítko je operátor dělení; pro dělení celych ?ísel se pou?ívá celo?íselné dělení se zbytkem, pou?itím desetinné te?ky u jednoho z operand? se vynutí reálné dělení. Hvězdi?ka je operátor násobení; pro ukon?ení interpretu lze pou?ít p?íkaz exit
nebo znak konce souboru, kterym je v Microsoft Windows a v MS-DOSu klávesová kombinace Ctrl-Z
, v Unixu Ctrl+D
. Aby bylo mo?né editovat p?íkazy pomocí kurzorovych kláves, musí byt nainstalován balí?ek tclreadline[3]; i bez něj lze p?íkazem history
vypsat seznam zadanych p?íkaz? a zvoleny p?íkaz znovu vyvolat zadáním vyk?i?níku a ?ísla p?íkazu.
Druhy interpret – wish
– je ur?eny pro programy pou?ívající grafické u?ivatelské rozhraní:
wish % wm title . "Hlavní okno" % wm minsize . 320 200 % label .l -text "Nápis v hlavním okně" .l % pack .l -padx 40 -pady 20 % toplevel .w2 .w2 % wm title .w2 "Druhé okno" % label .w2.l -text "Nápis v druhém okně" .w2.l % pack .w2.l -padx 10 -pady 10 %
– spu?těním wish
se otev?e hlavní okno okno aplikace; p?íkazy za?ínající wm
slou?í pro komunikaci se správcem oken: wm title
změní text v záhlaví okna a wm minsize
p?edepí?e jeho minimální velikost (?í?ka 320 pixel? a vy?ka 200 pixel?); p?íkaz label
p?ipraví nápis, ktery se provedením p?íkazu pack
zobrazí uvnit? okna; p?íkaz toplevel
vytvo?í druhé okno, kterému se dal?ími p?íkazy také změní text v záhlaví a ve kterém se vypí?e dal?í text; parametry za?ínající te?kou jsou obdobou cest pou?ívanych pro navigaci ve stromové struktu?e adresá?? na disku: samotná te?ka ozna?uje hlavní okno, .l
je prvek pojmenovany l
ve hlavním okně, .w2
je druhé okno a .w2.l
je prvek ve druhém okně (na konkrétních jménech l
a w2
nezále?í). P?íkazy vytvá?ející grafické prvky, jako label
a toplevel
, vracejí jméno prvku, které lze ulo?it do proměnnych a pou?ívat v dal?ích p?íkazech.
Obvyklej?í p?ístup je ale spou?tění p?edem p?ipravenych program? neboli skript?:
tclsh program.tcl parametr parametr ...
Parametry skriptu jsou dostupné jako seznam v proměnné argv
; po?et parametr? lze tedy zjistit pomocí llength $argv
. Dal?í mo?ností je ?tení proměnné argc
z globálního jmenného prostoru, tedy $::argc
. Jméno spu?těného skriptu je v proměnné argv0
.
Soubor?m s programy v jazyce Tcl se obvykle dává p?ípona .tcl
. Aby v Unixu bylo mo?né pou?tět Tcl skripty pouze zadáním jejich jména, je pot?eba dát souboru se skriptem právo execute a na jeho za?átek p?idat první ?ty?i ?ádky z následující ukázky:
#!/bin/sh
# -*- tcl -*-
# The next line is executed by /bin/sh, but not tcl \
exec tclsh "$0" ${1+"$@"}
puts "Hello, world!"
První ?ádek díky konstrukci Shebang zajistí, ?e se skript za?ne interpretovat programem /bin/sh; provedením p?íkazu exec
se spustí tclsh
, ktery za?ne ?íst soubor se skriptem zase od za?átku, ale ?ádek s p?íkazem exec
pova?uje za pokra?ování komentá?e z p?edchozího ?ádku díky jeho zakon?ení obrácenym lomítkem.
Syntaxe a základní sémantika
[editovat | editovat zdroj]Program (skript) v Tcl je tvo?en posloupností p?íkaz?. Ka?dy p?íkaz za?íná jménem p?íkazu, za kterym mohou následovat argumenty (parametry) oddělované od sebe navzájem i od jména p?íkazu v?dy alespoň jednou mezerou nebo tabulátorem. P?íkaz je ukon?en koncem ?ádku nebo st?edníkem. Jména p?íkaz? v Tcl nejsou vyhrazená slova, ani nemají v jazyce ?ádné zvlá?tní postavení; jsou to oby?ejné, nijak neprivilegované, funkce v knihovně. P?íkazy mohou mít proměnny po?et argument?.
p?íkaz argument1 argument2 ... argumentN
Pokud argumenty obsahují bílé znaky, musí byt uzav?eny ve dvojitych uvozovkách nebo ve slo?enych závorkách – pak m??e byt argument i více?ádkovy; pokud ale chcete od?ádkovat mezi argumenty, je nutné bezprost?edně p?ed od?ádkování napsat zpětné lomítko.
Symboly se zvlá?tním vyznamem
[editovat | editovat zdroj]$
– vrací hodnotu proměnné, její? jméno je uvedeno za znakem dolar[]
– závorky v?etně obsahu nahradí vystupem Tcl p?íkazu, ktery je v závorkách uzav?en""
– obsah uvozovek pova?uje za jediny argument, p?itom vyhodnocuje vno?ené konstrukce s$
,[]
a\
{}
– obsah závorek pova?uje za jediny argument, ale na rozdíl od uvozovek nevyhodnocuje konstrukce se speciální znaky uvnit?\
– ru?í zvlá?tní vyznam následujícího znaku nebo vytvá?í ?ídicí znak nebo znak se zadanym kódem#
– uvozuje komentá?, ktery kon?í s koncem ?ádku; lze pou?ít pouze v místě, kde m??e za?ínat p?íkaz
Apostrofy nemají v Tcl ?ádny zvlá?tní vyznam. Kulaté závorky se pou?ívají pro p?ístup k prvk?m asociativních polí a pro vyjád?ení priority v aritmetickych vyrazech.
P?íkaz puts
[editovat | editovat zdroj]P?íkaz puts
vypí?e zadany ?etězec (ktery musí tvo?it jedno slovo, proto je vhodné jej v?dy uzavírat do uvozovek) následovany znakem konce ?ádku, implicitně na standardní vystup (kanál stdout
):
puts "Hello, world!"
Pokud puts
nemá po vypsání ?etězce od?ádkovat, je pot?eba p?ed ?etězcem pou?ít volbu -nonewline
:
puts -nonewline "Hodnota proměnné i: "
puts $i
P?ed vypisovanym ?etězcem lze uvést jméno vystupního kanálu (nebo proměnnou, která se odkazuje na soubor):
puts stderr "Chyba!"
Proměnné a p?íkaz set
[editovat | editovat zdroj]Pro p?i?azení hodnoty do proměnné slou?í p?íkaz set
; pro získání obsahu proměnné je nutné p?ed její jméno napsat znak dolar:
% set x 5 5 % puts "Hodnota proměnné x je $x." Hodnota proměnné x je 5.
Pokud je p?íkaz set
zadán v p?íkazovém ?ádku tclsh (tj. p?i interaktivním provádění), vypisuje se p?i?azovaná hodnota; p?i provádění programu ne.
P?i?azení hodnoty vyrazu do proměnné není tak jednoduché; je pot?eba pou?ít p?íkaz expr
a hranaté závorky pro dosazení vysledku p?íkazu do jiného p?íkazu:
% set stupnu_Fahrenheita 451 451 % set stupnu_Celsia [expr {($stupnu_Fahrenheita-32)/1.8}] 232.77777777777777
P?ed otevírací hranatou i slo?enou závorkou musí byt mezera; první odděluje parametry p?íkazu set
, druhá jméno p?íkazu expr
od parametru.
Aby se odli?ilo jméno proměnné od okolního textu, lze jej uzav?ít do slo?enych závorek ${jmeno}
:
% set a 2 2 % set b 3 3 % puts "${a}x$b=[expr {$a*$b}]" 2x3=6
Tcl není staticky typovany jazyk: ka?dá proměnná m??e obsahovat hodnotu libovolného typu – nap?. celé ?íslo, reálné ?íslo, ?etězec, seznam, jméno p?íkazu nebo slovník; hodnoty se p?evádějí na jiné typy podle pot?eby automaticky (s omezeními danymi syntaxí). Hodnoty jsou ale v?dy konstantní (anglicky immutable); operace, které vypadají, ?e mění hodnoty, ve skute?nosti pouze vrací jinou hodnotu.
Asociativní pole
[editovat | editovat zdroj]Asociativní pole je slo?ená datová struktura, ve které se pro p?ístup k jednotlivym polo?kám pou?ívá klí?, kterym m??e byt libovolny textovy ?etězec. S prvky asociativních polí se pracuje stejně jako s jednoduchymi proměnnymi:
set hlavni_mesta(?R) "Praha"
set hlavni_mesta(Slovensko) "Bratislava"
set hlavni_mesta(Polsko) "Var?ava"
set hlavni_mesta(Německo) "Berlín"
set hlavni_mesta(Rakousko) "Vídeň"
set stat Slovensko
puts "Hlavní městem státu $stat je $hlavni_mesta($stat)."
Asociativní pole lze také vytvo?it pomocí p?íkazu array set
:
array set hlavni_mesta {
"?R" "Praha"
"Slovensko" "Bratislava"
"Polsko" "Var?ava"
"Německo" "Berlín"
"Rakousko" "Vídeň"
}
set stat Slovensko
puts "Hlavní městem státu $stat je $hlavni_mesta($stat)."
Oba skripty vypí?ou:
Hlavní městem státu Slovensko je Bratislava.
P?ítomnost prvku v poli lze testovat p?íkazem
info exists hlavni_mesta(Antarktis)
ktery vrací jedni?ku, pokud existuje zadany prvek v zadaném poli; jinak vrací nulu.
Asociativní pole (jako celek) nelze vypisovat p?íkazem puts
; lze pou?ít p?íkaz parray
ze standardní knihovny:
% puts $hlavni_mesta can't read "hlavni_mesta": variable is array % parray hlavni_mesta hlavni_mesta(Německo) = Berlín hlavni_mesta(Polsko) = Var?ava hlavni_mesta(Rakousko) = Vídeň hlavni_mesta(Slovensko) = Bratislava hlavni_mesta(?R) = Praha
Asociativní pole nelze p?edávat jako parametry procedur nebo je vracet jako návratové hodnoty funkcí; je mo?né pou?ít p?íkazy array set
a array get
, které provádějí p?evod mezi asociativním polem a seznamem:
% array get hlavni_mesta Německo Berlín Polsko Var?ava Slovensko Bratislava ?R Praha Rakousko Vídeň
Operátory seskupení
[editovat | editovat zdroj]P?ed provedením ka?dého p?íkazu Tcl provede vyhodnocení proměnnych a vno?enych p?íkaz? (tzv. substituce nebo expanze). Substituci lze ?ídit pomocí operátor? seskupení. Jazyk Tcl má 3 operátory seskupení:
- Uvozovky
""
- Slo?ené závorky
{}
- Hranaté závorky
[]
Operátory seskupení prop?j?ují jazyku Tcl nezaměnitelny charakter, jsou v?ak zároveň i p?í?inou, pro? se mu mnoho programátor? vyhybá.
Uvozovky
[editovat | editovat zdroj]Uvozovky se chovají stejně jako v mnoha jinych skriptovacích jazycích: vytvá?ejí ?etězec z posloupnosti slov a zároveň nezabraňují expanzi proměnnych ani vyhodnocování p?íkaz? zapsanych v hranatych závorkách. Pokud se mají do ?etězce vlo?it uvozovky, je nutné p?ed nimi napsat obrácené lomítko; obrácené lomítko také ru?í vyznam dolaru jako prost?edku pro expanzi hodnoty proměnné:
puts "Prvek $i pole \$arr má hodnotu \"$arr($i)\"."
Pokud je v proměnné i hodnota 8, a prvek pole $arr s indexem 8 (indexem m??e byt i ?etězec) obsahuje ?etězec "osmi?ka", vypí?e se
Prvek 8 pole $arr má hodnotu "osmi?ka".
V uvozovkách mají některé posloupnosti za?ínající znakem obrácené lomítko vyznam ?ídicích nebo jinych znak?:
Posloupnost | Vyznam |
---|---|
\n | Znak novy ?ádek (line feed) |
\r | Znak návrat vozíku (carriage return) |
\t | Znak tabelátor (tab) |
\v | Znak vertikální tabelátor (vertical tab) |
\a | Znak zvonek (bell) |
\b | Znak backspace |
\0nn | Znak se zadanym kódem (v osmi?kové soustavě) |
\uHHHH | Unicode znak U+HHHH |
\xHH | Znak se zadanym kódem (v ?estnáctkové soustavě) |
Hranaté závorky
[editovat | editovat zdroj]Do hranatych závorek lze zapsat libovolny p?íkaz Tcl v?etně parametr?; p?íkaz v hranatych závorkách se provede p?ed provedením p?íkazu, ve kterém je pou?it, a hranaté závorky se nahradí vystupem, ktery vyprodukuje. V následujícím p?íkladu je pou?it p?íkaz clock seconds
, ktery vrací po?et sekund od 1. 1. 1970 a p?íkaz clock format
, ktery tento údaj zformátuje podle parametru uvedeného za volbou -format
:[4]
puts "Od 1. ledna 1970 uplynulo [clock seconds] sekund;"
puts "Je rok [clock format [clock seconds] -format "%Y"]."
vypí?e
Od 1. ledna 1970 uplynulo 1366380049 sekund; Je rok 2013.
Jak je vidět, hranaté závorky a uvozovky lze vno?ovat.
Nej?astěj?í p?íkaz, ktery se pí?e do hranatych závorek, je p?íkaz expr
, ktery vyhodnocuje aritmetické vyrazy:
set vyraz "1+2+3+4+5+6+7+8+9+10"
set vysledek [expr $vyraz]
puts "Sou?et $vyraz je $vysledek."
Vypí?e
Sou?et 1+2+3+4+5+6+7+8+9+10 je 55.
Substituce pomocí hranatych závorek umo?ňuje pou?ít vysledek jednoho p?íkazu jako argument dal?ího p?íkazu. Pokud se má vyvolat p?íkaz jako funkce, která vrací hodnotu, musí se v?dy uzav?ít do hranatych závorek.
Tcl nepot?ebuje operátor pro spojení ?etězc?, proto?e sta?í jenom zapsat proměnné nebo p?íkazy v hranatych závorkách za sebe. Na rozdíl od unixovych interpret? p?íkaz? vyhodnocuje Tcl ka?dy ?etězec pouze jednou (pokud skript p?ímo nep?edepisuje opakované vyhodnocení), co? trochu komplikuje interaktivní pou?ití, ale zpr?hledňuje chování ve skriptech (nap?. mezery ve jméně souboru nep?sobí potí?e známé z unixovych shell?).
Slo?ené závorky
[editovat | editovat zdroj]Slo?ené závorky se chovají jako apostrofy v unixovych interpretech p?íkaz? a některych skriptovacích jazycích – jejich obsah se bere jako jedno slovo a nijak se neexpanduje (jen se ignoruje konec ?ádku, p?ed kterym je zpětné lomítko). Slo?ené závorky se mohou pou?ívat pro zápis ?etězc?, které se mají interpretovat p?esně tak, jak jsou zapsány, v Tcl v?ak mají mnohem ?ir?í pou?ití – pro zápis seznam? a ?ídicích struktur. Cyklus s testem na za?átku se v Tcl zapisuje jako p?íkaz while
, za kterym následují dvě slova – první je podmínka, druhé je tělo cyklu. Tcl nevy?aduje ?ádné závorky, do kterych by se podmínka a tělo cyklu uzavíralo, ale nejsnaz?í zp?sob, jak podmínku i tělo cyklu zapsat jako jedno slovo, je uzav?ít je do slo?enych závorek. Díky tomu se zápis while cyklu v Tcl podobá zápisu v jazyce C. Podobnym zp?sobem se zapisuje definice funkce (první parametr za slovem proc
je jméno procedury nebo funkce, druhy seznam parametr?, t?etí tělo funkce), podmíněny p?íkaz (první parametr za slovem if
je podmínka, druhym seznam p?íkaz?, které se mají provést, je-li podmínka splněna, pak mohou následovat ?ásti elseif
a else
).
Do slo?enych závorek se také uzavírají matematické vyrazy vyhodnocované p?íkazem expr
.
Pokud by se v p?íkazu puts
pou?itém v ?ásti ?Uvozovky“ nahradily vněj?í uvozovky slo?enymi závorkami:
puts {Prvek $i pole \$arr má hodnotu \"$arr($i)\".}
vysledny vystup by vypadal zna?ně odli?ně; pravděpodobně úplně jinak, ne? bylo zamy?leno:
Prvek $i pole \$arr má hodnotu \"$arr($i)\".
Pokud jsou slo?ené závorky vno?eny do jinych slo?enych závorek, hranatych závorek nebo uvozovek, chovají se jako normální znak:
puts "Prvek {$i} pole \$arr má hodnotu {$arr($i)}."
vypí?e
Prvek {8} pole $arr má hodnotu {osmi?ka}.
Do slo?enych závorek se uzavírají vyrazy v p?íkazu expr
, aby se zabránilo dvojí expanzi jména proměnnych:
set i 10
set d "\$i"
puts [expr 2*$d]
?ídicí struktury
[editovat | editovat zdroj]V Tcl jsou dostupné obvyklé ?ídicí struktury:
if
elseif
else
– podmíněny p?íkazswitch
– vícecestné větveníwhile
– cyklus s testem na za?átkufor
– cyklus s ?ídicí proměnnouforeach
– cyklus p?es prvky seznamu
Díky vynalézavému pou?ití slo?enych závorek je zápis ?ídicích struktur podobny jako v jazyce C; v Tcl se v?ak do slo?enych závorek pí?ou nejen p?íkazy, ale i podmínky. Interpretu Tcl je skute?nosti jedno, jaké operátory seskupení se pou?ijí (a jestli v?bec nějaké). Vy?aduje pouze, aby slova uvozující jednotlivé konstrukce měly správny po?et argument?/parametr?. Nap?íklad v p?íkazu cyklu while
musí byt za jménem p?íkazu dva argumenty: první je podmínka, druhy tělo cyklu. A nejjednodu??ím zp?sobem, jak sdělit Tcl, ?e ur?ity text má pova?ovat za jeden parametr, je uzav?ít jej do slo?enych závorek. Proto?e parametry musí byt odděleny aspoň jednou mezerou, musí byt vně slo?enych závorek (tj. p?ed {
a za }
) v?dy aspoň jeden bíly znak (mezera nebo tabelátor). Otevírací závorka těla cyklu musí byt na stejném ?ádku jako podmínka (nebo musí byt p?edchozí ?ádek zakon?en zpětnym lomítkem).
Podmíněny p?íkaz
[editovat | editovat zdroj]Následující program ukazuje syntaxi podmíněného p?íkazu v Tcl; ?ást else
je nepovinná, p?íkaz m??e mít libovolny po?et ?ástí elseif
:
if {$i > 0} {
puts "$i je kladné ?íslo"
} elseif {$i == 0} {
puts "$i je nula"
} else {
puts "$i je záporné ?íslo"
}
While cyklus
[editovat | editovat zdroj]Následující ukázka pou?ití while
p?íkazu po?ítá Ludolfovo ?íslo podle vzorce
kde funkce arkus tangens se po?ítá pomocí Taylorova vzorce
- (pro )
set platnych_mist 12
set epsilon "1e-$platnych_mist"
set znam 1.0
set moc2 [expr {1.0/2.0}]
set moc3 [expr {1.0/3.0}]
set n 1
set clen [expr {$moc2+$moc3}]
set suma $clen
while {abs($clen)>$epsilon} {
incr n 2
set znam [expr {-$znam}]
set moc2 [expr {$moc2/4.0}]
set moc3 [expr {$moc3/9.0}]
set clen [expr {$znam/$n*($moc2+$moc3)}]
set suma [expr {$suma+$clen}]
}
puts "Ludolfovo ?íslo: [format "%.${platnych_mist}G" [expr {4.0*$suma}]]"
P?íkaz incr
zvět?í hodnotu proměnné, která je jeho prvním parametrem, o hodnotu zadanou druhym parametrem (nebo o 1, pokud druhy parametr chybí).
Pro ukon?ení provádění cyklu lze pou?ít p?íkaz break
.
For cyklus
[editovat | editovat zdroj]V p?ípadě for cyklu se do vlastních slo?enych závorek dává ka?dy ze t?í vyraz?, které se v jazyce C pí?ou do kulatych závorek a oddělují st?edníky:
for {set i 1} {$i <= 10} {incr i} {
puts "$i"
}
Pro ukon?ení provádění cyklu lze pou?ít p?íkaz break
, pro zahájení dal?ího pr?chodu cyklem p?íkaz continue
. V Tcl existuje i p?íkaz cyklu p?es v?echny prvky seznamu foreach
, ktery je popsán u seznam?.
Definice funkcí
[editovat | editovat zdroj]Funkce se v Tcl definují p?íkazem proc
, za kterym následují dvojí slo?ené závorky; první obsahují seznam parametr? (oddělenych mezerami), druhé tělo funkce. Pokud má funkce vracet návratovou hodnotu, lze pou?ít p?íkaz return
(jinak vrací vysledek posledního provedeného p?íkazu). Naprogramovat vypo?et faktoriálu rekurzivně sice není ideální, ale je to mo?né i v Tcl. V?imněte si, ?e Tcl umo?ňuje, aby jméno funkce byl vyk?i?ník:
proc ! {n} {
if {$n <= 1} {
set res 1
} else {
set res [expr {$n * [ ! [expr {$n - 1}] ]} ]
}
return $res
}
for {set n 1} {$n <= 20} {incr n} {
puts "$n! = [! $n]"
}
Vhodněj?í vypo?et faktoriálu bez rekurze by mohl vypadat takto:
proc ! {n} {
set res 1
for {set k 2} {$k <= $n} {incr k} {
set res [expr {$res*$k}]
}
return $res
}
for {set n 1} {$n <= 20} {incr n} {
puts "$n! = [! $n]"
}
U?ivatelem definované funkce se volají stejně jako ostatní p?íkazy – parametry se pí?ou za jméno funkce a od jména funkce i sebe navzájem se oddělují mezerami nebo bílymi znaky. Proto p?i volání funkce faktoriál není mo?né psát (jako v matematice) vyk?i?ník za vyraz, z něho? se má faktoriál po?ítat.
Vět?ina p?íkaz? jazyka Tcl jsou funkce s proměnnym po?tem parametr?. To platí i o p?íkazech ve standardní knihovně. P?íkaz proc
(konstruktor pro vytvá?ení procedur/funkcí) umo?ňuje definovat implicitní hodnoty pro argumenty, které nebudou pou?ity ve volání procedury, a parametr obsahující v?echny argumenty, co? umo?ňuje zpracování proměnného po?tu argument? ve funkcích.
P?ístup k globálním proměnnym
[editovat | editovat zdroj]Proměnné pou?ité mimo funkci nejsou uvnit? funkce viditelné. Pro jejich zp?ístupnění lze uvnit? funkce pou?ít p?íkaz
global
proměnná
Modifikace parametr? funkce
[editovat | editovat zdroj]Pokud mají byt změny hodnot některého z parametr? funkce viditelné i po opu?tění funkce, je nutné pou?ít p?edávání parametr? odkazem. V tcl lze pou?ít následující konstrukci:
# Funkce vrátí kód bytu (0-255) z pozice idx v ?etězci buffer a zvět?í idx o 1
# Je-li idx >= ne? délka bufferu, vrátí -1 a idx nezmění
proc get_first_octet {buffer idx} {
# na parametr idx se budeme odkazovat pomocí $pos
upvar 1 $idx pos
if {$pos < [string length $buffer]} {
binary scan [string index $buffer $pos] c octet
incr pos
return [expr {$octet & 0xFF}]
} else {
return -1
}
}
P?i volání funkce se na místě parametru p?edávaného odkazem pí?e pouze jméno proměnné bez znaku dolar:
set retezec "Abcd"
set i 0
set kod [get_first_octet $retezec i]
Implicitní parametry funkce
[editovat | editovat zdroj]Místo posledního nebo několika posledních parametr? v definici funkce mohou byt pou?ity dvojice {jméno hodnota}
. Ve volání funkce pak mohou tyto parametry chybět. P?i vstupu do funkce se jim p?i?adí hodnoty uvedené v seznamu parametr?.
Funkce s proměnnym po?tem parametr?
[editovat | editovat zdroj]Pokud se poslední parametr v definici funkce jmenuje args
, je mo?né tuto funkci vyvolat s vět?ím po?tem parametr?, ne? je uvedeno v definici. Parametr args
pak bude obsahovat seznam v?ech zbyvajících parametr?, ktery lze zpracovávat funkcemi uvedenymi v ?ásti Práce se seznamy.
Funkce vracející více hodnot
[editovat | editovat zdroj]Pokud má funkce vracet více hodnot, lze je vrátit v podobě seznamu, ktery lze zkonstruovat funkcí list
:
return [list "Error" "Soubor $filename nelze ?íst"]
Vrácenou hodnotu lze zpracovávat pomocí funkcí uvedenych v ?ásti Práce se seznamy.
Funkce s klí?ovymi parametry
[editovat | editovat zdroj]Někdy je pot?eba definovat funkce, které pracují s velkym po?tem parametr?, ale p?i konkrétním vyvolání se jich pou?ívá jenom několik málo, p?i?em? uvnit? funkce se za ostatní dosadí vhodné implicitní hodnoty. Pokud lze set?ídit parametry od nejpou?ívaněj?ích po nejméně pou?ívané, m??e se volání funkcí zkrátit pou?itím implicitních parametr?. Jinak je lep?í rezignovat na p?ístup, ?e vyznam parametru je dán jeho po?adím (pozi?ní parametry), a pou?ít klí?ové parametry, kdy se seznam parametr? zadává ve tvaru seznamu dvojic jméno1 hodnota1 jméno2 hodnota2 .... Aby se snadno odli?ila jména parametr? od hodnot, pou?ívají se ?asto jména za?ínající znakem minus, podobně jako p?epína?e (volby) v p?íkazovém ?ádku. Pro zpracování klí?ovych parametr? lze v Tcl pou?ít následující postup:[5]
proc moje_funkce {args} {
if {[catch {array set moje_parametry $args} msg]} {
return $msg
}
# Parametry jsou nyní dostupné jako moje_parametry(jméno)
parray moje_parametry
}
moje_funkce -pocet 3 -retezec "abc"
Funkce parray
z knihovny Tcllib vypí?e p?ehledně prvky pole:
moje_parametry(-pocet) = 3 moje_parametry(-retezec) = abc
R?zné p?íkazy a funkce
[editovat | editovat zdroj]Seznam dostupnych p?íkaz? (v?etně u?ivatelem nadefinovanych funkcí) lze vypsat p?íkazem:
join [lsort [info commands]] "\n"
P?esto?e v Tcl je ka?dá funkce zároveň p?íkazem a naopak p?íkaz ?asto vrací nějakou hodnotu – nap?íklad p?íkazy incr
a append
vracejí novou hodnotu pou?ité proměnné – v následujícím textu jsou rozli?ovány funkce (které budou v programu pou?ity v hranatych závorkách) od celych p?íkaz?.
Práce se seznamy
[editovat | editovat zdroj]Seznam je v tcl libovolny ?etězec, v něm? jsou jednotlivé prvky odděleny mezerami. Pokud prvky seznamu obsahují mezery, Tcl je uzavírá do slo?enych závorek. Pomocí slo?enych závorek lze velmi jednodu?e vytvá?et víceúrovňové konstantní seznamy, nap?.
set slovnicek {
{{u?it} {teach taught taught}}
{{u?it se} {learn {learnt learned} {learnt learned}}}
}
Pro vytvá?ení seznam? obsahujících hodnoty proměnnych a vyraz? lze pou?ít p?íkaz list
nebo subst
.
Jednotlivé prvky lze vybírat pomocí funkce lindex
.
list
[ hodnota ... ] – funkce vrací seznam tvo?eny zadanymi prvky; oproti p?edchozímu p?íkladu mohou jednotlivé argumenty obsahovat proměnné nebo byt tvo?eny vyrazyllength
seznam – funkce vrací po?et prvk? v seznamu –llength "abc 2 xyz"
vrací 3; není-li seznam korektním seznamem, skon?í chybouunmatched open brace in list
lindex
seznam ?íslo_prvku – funkce vrací zadany prvek seznamu (prvky se ?íslují od 0) –lindex {a b c} 2
vracíc
; prvek lze kromě ?ísla zadat i ?etězcemend
(konec ?etězce) nebo ve tvaru ?íslo+?íslo, ?íslo-?íslo,end
+?íslo neboend
-?íslo (zápis pozice nesmí obsahovat mezery); není-li seznam korektním seznamem, skon?í chyboulset
proměnná index hodnota – p?íkaz nastaví prvek seznamu se zadanym indexem na zadanou hodnotulreplace
seznam n1 n2 [ hodnota ... ] – funkce vrátí seznam, ktery vznikne ze zadaného seznamu nahrazením prvk? n1 a? n2 zadanymi hodnotami (po?et vypou?těnych a vkládanych prvk? nemusí souhlasit)linsert
seznam index [ hodnota ... ] – funkce vrátí seznam, do kterého jsou p?ed pozici index vlo?eny zadané hodnotylappend
proměnná [ hodnota ... ] – p?íkaz p?ipojí zadané hodnoty na konec seznamu v zadané proměnné (a vrátí vysledny seznam); neobsahuje-li proměnná korektní seznam, skon?í chyboulsearch
[ -volby ... ] seznam vzorek – funkce vrátí index prvního prvku seznamu, ktery vyhovuje zadanému vzorku; s volbou-regexp
je vzorek pova?ován za regulární vyraz, s volbou-glob
za ?olíkovy vyraz, s volbou-exact
se provádí p?esné porovnání (implicitně ?etězc?, je-li uvedena navíc volba-integer
, pak celych ?ísel, s volbou-real
?ísel s pohyblivou ?ádovou ?árkou); není-li vzorek v seznamu, vrátí-1
; není-li seznam korektním seznamem, skon?í chybousplit
?etězec oddělova? – funkce vrátí seznam tvo?eny ?etězcem rozdělenym na ?ásti v místech oddělova??; je-li oddělova? prázdny, vrátí ?etězec rozděleny na jednotlivé znakyjoin
seznam oddělova? – funkce spojí prvky seznamu pomocí oddělova?? a vrátí jako jeden ?etězecforeach
{ seznam jmen proměnnych } seznam { p?íkazy } – p?íkaz realizující cyklus p?es cely seznam; p?i ka?dém pr?chodu zpracuje tolik polo?ek seznamu, kolik proměnnych je v seznam jmen proměnnych a p?i?adí je zadanym proměnnym; p?íkazy se provádí opakovaně, dokud se nevy?erpají v?echny prvky seznamu; pokud se v posledním pr?chodu nedostává hodnot pro v?echny proměnné, naplní zbytek proměnnych prázdnymi ?etězci; v těle cyklu lze pou?ívat p?íkazybreak
acontinue
.
Někdy se pou?ívá trik pro ulo?ení několika prvních hodnot seznamu do proměnnych pomocí p?íkazu foreach
, jeho? tělo je tvo?eno p?íkazem break
: nap?íklad ulo?ení pro ulo?ení prvního prvku seznamu do proměnné var1
a t?etího prvku do var3
(druhy prvek, o ktery nestojíme, se ulo?í do proměnné -
) lze pou?ít p?íkaz:
foreach {var1 - var3} seznam break
Práce s ?etězci
[editovat | editovat zdroj]string length
?etězec – funkce vrací délku ?etězce; u binárních ?etězc? vrací délku v bytech, u znakovych ve znacíchstring bytelength
?etězec – funkce vrací po?et byt? pou?itych pro reprezentaci zadaného ?etězce v paměti; pro binární ?etězce vrací nesmyslné hodnoty; tato funkce je pravděpodobně pro programování v Tcl zcela nepou?itelná[6]string index
?etězec pozice – funkce vrací znak na dané pozici ?etězce (?íslováno od 0); pozici lze kromě ?ísla zadat i ?etězcemend
(konec ?etězce) nebo ve tvaru ?íslo+?íslo, ?íslo-?íslo,end
+?íslo neboend
-?íslo (zápis pozice nesmí obsahovat mezery)string range
?etězec from to – funkce vrací pod?etězec od pozice from do pozice to v?etně (?íslováno od 0); from i to lze zadat stejně jako pozici vestring index
string first
vzorek ?etězec [ start ] – funkce vrací pozici prvního vyskytu ?etězce vzorek v zadaném ?etězci od pozice start (?íslováno od 0); p?i neúspěchu vrátí -1append
proměnná seznam – p?íkaz spojí v?echny prvky seznamu do jednoho ?etězce (nic mezi ně nevkládá) a ten p?ipojí na konec obsahu proměnnéstring map
mapa ?etězec – funkce vrátí ?etězec vznikly z posledního parametru nahrazením pod?etězc? podle mapy; mapa je seznam dvojic pod?etězec náhrada; nahrazuje v?dy první nalezeny pod?etězec, nikoli nejdel?ístring reverse
?etězec – funkce vrací zadany ?etězec pozpátkustring repeat
?etězec po?et – funkce vrací ?etězec vznikly zadanym po?tem opakování zadaného ?etězcestring compare
[ -nocase ] [ -length n ] ?etězec1 ?etězec2 – porovná ?etězce a vrátí -1 (?etězec1 je p?ed ?etězec2), 0 (?etězce jsou stejné) nebo 1- od verze Tcl 8.4 lze pou?ívat pro porovnávání ?etězc? infixové operátory
eq
(je rovno) ane
(není rovno)
Regulární vyrazy
[editovat | editovat zdroj]regexp
[ volby ] reg_vyraz ?etězec [ proměnná ... ] – funkce vrátí jedni?ku, pokud zadany ?etězec vyhovuje regulárnímu vyrazu reg_vyraz; pokud jsou uvedeny proměnné, ulo?í se do první pod?etězec, na ktery byl napasován cely regulární vyraz, do dal?ích pod?etězce, které byly napasovány na podvyrazy zapsané v reg_vyraz v kulatych závorkách; volby mohou byt-nocase
– nerozli?ují se velká a malá písmena;-start
pozice – shoda se hledá a? od zadané pozice-indices
– do proměnnych se neukládají pod?etězce ale dvojice ?ísel, udávající po?áte?ní a koncovou pozici v ?etězci; pod?etězec lze získat pomocístring range
?etězec[lindex $pos 0] [lindex $pos 1]
, kdepos
je jméno proměnné, do které byla ulo?ena dvojice pozic, která nás zajímá; pro Tcl od verze 8.5 lze pou?ítstring range
?etězec{*}$pos
; prefix{*}
zajistí, ?e jednotlivá slova z proměnné$pos
budou pova?ována za samostatné parametry p?íkazustring range
regsub
[volby] reg_vyraz ?etězec náhrada vysledek – funkce vrátí po?et úspě?nych nahrazení pod?etězc? vyhovujících reg_vyraz v zadaném ?etězci vyrazem náhrada; do parametru vysledek ulo?í vysledek nahrazování; nejpou?ívaněj?í volbou je-all
, která znamená, ?e se mají nahrazovat v?echny nalezené vyskyty, jinak se provede náhrada pouze prvního vyskytu
Práce se soubory
[editovat | editovat zdroj]open
jméno – funkce otev?e nebo vytvo?í soubor a vrátí manipulátor souboruclose
manipulátor – funkce zav?e souborputs
[manipulátor] ?etězec – p?íkaz zapí?e zadany ?etězec do souborugets
manipulátor [proměnná] – funkce na?te jeden ?ádek ze souboru a ulo?í ho do zadané proměnné, vrátí po?et p?e?tenych byt? nebo-1
na konci souboru; není-li uvedeno jméno proměnné vrací na?teny ?ádek – v tomto p?ípadě je nutné testovat konec souboru pomocí funkceeof
!read
manipulátor [délka] – funkce na?te blok zadané délky ze souborufconfigure
[manipulátor] parametry – p?íkaz nastaví re?im práce se souborem (nap?. nebufferovany, bez ?ekání, binární bez konverzí kódování a konc? ?ádk?)
Konverze dat
[editovat | editovat zdroj]format
formát hodnota [ ... ] – funkce vrací ?etězec formát vyplněny v místech formátovacích direktiv zadanymi hodnotami – jako funkce sprintf v jazyce Cscan
?etězec formát [proměnná [ ... ]] – funkce na?ítá z ?etězce hodnoty zadané formátem a plní jimi proměnné jako funkce sscanf v jazyce C; vrací po?et naplněnych proměnnychbinary format
formát ?etězec – funkce vrací ?etězec vznikly interpretací zadaného ?etězce zadanym formátem;binary format B* 0100000101000010
vracíAB
, proto?e01000001
je binární zápis kódu písmeneA
a01000010
binární zápis kódu písmeneB
binary scan
vstup formát vystup – p?íkaz ulo?í do proměnné $vystup hodnotu vzniklou interpretací vstupu zadanym formátem –binary scan $line B* bitstring
ulo?í do$bitstring
binární zápis obsahu proměnné$line
;binary scan ABC12 H* output; puts $output
vypí?e reprezentaci znak?v ?estnáctkové soustavě
4142433132
encoding convertto
vystupní_kódování vstup – funkce vrací vstup zkonvertovany do zadaného kódováníencoding convertfrom
vstupní_kódování vstup – funkce vrací vstup zkonvertovany ze zadaného kódování – pro konverzi z UTF-16 do UTF-8 je nutné pou?ít[encoding convertto utf-8 [encoding convertfrom unicode $vstup]]
Jmenné prostory
[editovat | editovat zdroj]Mechanismus jmennych prostor? vytvá?í stromovou strukturu, v jejich? r?znych uzlech jsou identifikátory proměnnych a funkcí (p?íkaz?). To umo?ňuje pou?ívat v jednom programu více knihoven sou?asně bez problém? s konflikty ve jménech funkcí a proměnnych. Vyběr jmenného prostoru identifikátoru se provádí pomocí kvalifikovanych jmen tvaru ::prostor::podprostor::atd::identifikátor
, p?i?em? kvalifikované jméno pro identifikátory v základním (ko?enovém) jmenném prostoru je ::identifikátor
.
Pro práci se jmennymi prostory slou?í p?íkaz namespace
, jeho? první parametr udává, jaká operace se jmennymi prostory se má provést. Pro vytvo?ení nebo opětovny vstup do jmenného prostoru slou?í p?íkaz namespace eval jméno_prostoru kód
, kde kód
je libovolná posloupnost p?íkaz? v Tcl. V?echny proměnné a funkce, které budou v rámci p?íkazu namespace eval jméno_prostoru
definovány bez uvedení kvalifikovaného jména, budou pat?it do p?íslu?ného jmenného prostoru. P?i pou?ití nekvalifikovaného jména se identifikátor nejd?íve vyhledává v aktuálním jmenném prostoru; není-li v něm nalezen, postup dal?ího vyhledávání závisí na tom, o jaky identifikátor se jedná; zatímco proměnné se hledají je?tě v ko?enovém jmenném prostoru, p?íkazy se hledají postupně ve v?ech nad?ízenych jmennych prostorech aktuálního prostoru. Hierarchické jmenné prostory se vytvá?ejí vno?enymi p?íkazy namespace eval
.
Roz?i?itelnost
[editovat | editovat zdroj]V Tcl lze ka?dou funkci chápat jako roz?í?ení jazyka – p?íkaz info commands
za?ne vracet, ?e p?íkaz p?íslu?ného jména existuje. Tímto zp?sobem lze do star?í verze Tcl doimplementovat p?íkaz, ktery je dostupny v nověj?ích verzích. Dostupnost p?íkazu lze testovat pomocí info commands jméno_p?íkazu
nebo namespace which jméno_p?íkazu
.
Zpracování vyjimek
[editovat | editovat zdroj]Pro o?et?ení chyb (vyjimek) p?i provádění programu poskytuje Tcl p?íkaz catch
. Konstrukce
catch {skript} jméno_proměnné
se chová podobně jako
set jméno_proměnné [skript]
ale p?i úspě?ném provedení p?íkazu nebo p?íkaz? v ?ásti skript
vrací hodnotu 0. V p?ípadě, ?e p?i provádění skriptu dojde k jakékoli chybě, p?i?adí se do zadané proměnné text chyby a p?íkaz catch
vrátí hodnotu 1. Dal?í mo?nosti vyu?ití p?íkazu catch
jsou popsány v dokumentaci.
Následující funkce otestuje, zda lze otev?ít spojení na soket na zadané IP adrese a si?ovém portu:
proc check_socket {{ip "127.0.0.1"} {port 23}} {
if { [catch {socket $ip $port} fid ] } {
puts "Chyba: spojení na $ip:$port nelze otev?ít"
} else {
puts "OK: spojení na $ip:$port se poda?ilo otev?ít"
close $fid
}
}
check_socket {*}$argv
Odkazy
[editovat | editovat zdroj]Reference
[editovat | editovat zdroj]- ↑ LERDORF, Rasmus. PHP on Hormones – history of PHP presentation by Rasmus Lerdorf given at the MySQL Conference in Santa Clara, California [online]. The Conversations Network, 2025-08-07. Dostupné online.
- ↑ Windows PowerShell : PowerShell and WPF: WTF. blogs.msdn.com [online]. [cit. 2025-08-07]. Dostupné v archivu po?ízeném dne 2025-08-07.
- ↑ tclreadline; GNU readline for interactive tcl shells [online]. [cit. 2025-08-07]. Dostupné online.
- ↑ scripting/syntax, Kapitola: A Little Example.
- ↑ How to create tcl proc with hyphen flag arguments [online]. stackoverflow, 2025-08-07 [cit. 2025-08-07]. Dostupné online.
- ↑ FELLOWS, Donal. string bytelength [online]. wiki.tcl.tk. Dostupné online.
Literatura
[editovat | editovat zdroj]- An Introduction to Tcl Syntax [online]. [cit. 2025-08-07]. Dostupné online.
Související ?lánky
[editovat | editovat zdroj]Externí odkazy
[editovat | editovat zdroj]Obrázky, zvuky ?i videa k tématu Tcl na Wikimedia Commons
- (anglicky)
- Tcl/Tk Wiki
- Tcl/Tk Home Page
- úvod do Tcl
Kniha en:Tcl Programming ve Wikiknihách – rozsáhly text s ukázkami kompletních program?
- (?esky)