Tcl kalba

Taip pat trumpas Tcl pristatymas (su procedūros pavyzdžiu) >>>>>

Pravartu paskaityti apie programavimo kompiuteriams palyginimą su kitais realaus gyvenimo aprašais > >>> >

Tcl (iš Tool Command Language, tačiau retai rašoma kaip TCL, o tariama kaip „tikl“) – yra interpretuojama kalba, kurią 1988 m. sukūrė Džonas Osterhoutas (John Ousterhout), tuo metu dirbęs Berklio Kalifornijos un-te. Anot jo, jis ją sukūrė iš „susierzinimo“, kad kiekvienas programuotojas kuria nuosavą kalbą taikomosioms programas. Tcl buvo sumanyta kaip universali kalba tokiems taikymams. Ji greitai išpopuliarėjo, per 4 m. ją naudojo jau keli šimtai tūkstančių programuotojų. Ji paprastai naudoja greitam prototipų sukūrimui, kaip vidinė taikomųjų programų kalba, grafinėse aplinkose ir testavimui. Naudojama ir internetiniams sprendimams.

Gan greitai Dž. Osterhoutas Tcl kalbą išplėtė grafinėmis sąsajomis – šis variantas įgavo Tcl/Tk (tariama „tikl-tok“).

1990 m. buvo paskelbta apie „Expect“, Don Libes sukurtą tcl išplėtimą, skirtą interaktyvią sąsają turinčių programų valdymo automatizavimui. Tai programos telnet, ftp, sftp, passwd, ssh ir kitos.

1998 m. už Tcl Dž. Osterhoutas gauna du apdovanojimus: ACM „Software System Award“, skiriamą už „reikšmingą programinę įrangą“bei USENIX STUG apdovanojimą, kaip pripažintos PO ženklą.

Dabar Tcl galima naudojimui ne vien įvairiose Unix atmainose (Linux, Solaris, AIX, *BSD*, IRIX, HP-UX ir kt.) bet ir “Windows” bei “Mac OS”.

Parsisiųsti: >>>>>

Pastaba: pateikiamus pavyzdžius ir paaiškinimus pateiksiu kaip vykdytus „Unix“ klasės operacinėje sistemoje. O konkrečiai - naudojausi Aix 6.1.8.0 aplinka.

Pirmoji programa

Kaip visada, ja bus apie save paskelbianti „Labas, pasauli!“ programa :

puts "Labas, pasauli!"

Dabar įvykdykime šią mūsų pirmąją programą. Pirmiausia užrašykime ją į failą, tarkim labas.tcl Tada iškvieskime Tcl kalbos interpretatorių ir jam nurodykime failą su programos tekstu. Minėjome du Tcl kalbos interpretatorius, tad tai galima atlikti dviem komandomis:
tclsh labas.tcl
arba
expect labas.tcl

Pirmoji iškviečia Tcl interpretatorių, o antroji - expect interpretatorių. Tačiau yra galimybė pačioje programoje nurodyti, kurį interpretatorių naudoti. Tam pirmoje eilutėje įveskite nuorodą į interpretatorių, pvz.,

#!/usr/bin/tclsh
puts "Labas, pasauli!"

arba

#!/usr/bin/expect
puts "Labas, pasauli!"

Tačiau tada papildomai reikia nurodyti, kad failas yra „vykdomasis“, - tai galima atlikti tokio tipo „Unix“ komanda:
chmod a+x labas.tcl
o programą vykdyti tiesiog nurodant failo vardą:
./labas.tcl

Tolyn į mišką - Tcl sintaksė

Dabar trumpai pristatysime bendruosius Tcl sintaksės principus.

Programos sudarytos iš komandų, kurias skiria eilučių pabaigos arba kabliataškiai ( ; ).
Komandą sudaro tarpais atskirti žodžiai, kurių pirmasis yra komandos vardas, o kiti – jos argumentai, t.y.:
komanda argumentas1 argumentas2 … argumentasN

Bet kuriuo argumentu gali būti kita komanda apgaubta laužtiniais skliaustais [ … ]
Jei norima kelis žodžius „kaip yra“ (t. y., be kintamųjų reikšmių įstatymų) perduoti komandai kaip vieną argumentą, jie apgaubiami riestiniais skliaustais { … }.

Specialus dolerio ( $ ) ženklas naudojamas nuorodai, kad reikia įstatyti kintamojo reikšmę, o atvirkščias brūkšnys ( \ ) įtraukia ženklą po jo kaip simbolį, o ne valdantį ženklą. Tekstas kabutėse ( "…" ) taip pat grupuoja žodžius į vieną argumentą, tačiau, skirtingai nuo riestinių skliaustų { … }, leidžia įtraukti kintamųjų reikšmes.

Prieš iliustruojant tai pavyzdžiais, pristatysime vieną Tcl kalbos komandą, kurią panaudosime iliustracijose. Tai reikšmės priskyrimo kintamajam komanda set:
set kintamasis reikšmė
pvz.,

set penki 5
set draugai "Antanas ir Petras"
set list {vienas ir du}

Pavyzdžiai:

1. Kintamųjų reikšmių įtraukimas:
puts "Skaičius: $penki, tekstas: $draugai"
Išvedama:
Skaičius: 5, tekstas: Antanas ir Petras

2. Specialių ženklų išvedimas:
puts "Su doleriu $penki \[set x 9\] \{ ... \} ir \"brūkšnys\" \ - spec. ženklai"

Išvedama:
Su doleriu $penki [set x 9] { ... } ir "brukšnys" \ - spec. ženklai

3. Pateikimas “kaip yra”:
puts {Tekstas "kaip yra" $penki}

Išvedama: Tekstas "kaip yra" $penki

4. Įdėtinės komandos vykdymas:
puts "Priskyrimas: [set x 9] $x"

Išvedama: Priskyrimas: 9 9

Paskutinio pavyzdžio trumpas paaiškinimas:
puts vykdymo metu atliekamas 9 priskyrimas kintamajam x, o vėliau jau išvedama paties kintamojo x reikšmė – todėl reikšmė „9“ pateikiama dukart.

5. Sisteminės komandos vykdymas – veiksnaus katalogo priskyrimas:

#!/usr/bin/tclsh
set aplankas [pwd]
puts "Aktyvus aplankas: $aplankas"

Ši programa kintamajam aplankas priskirs veiksnaus katalogo pavadinimą, pvz., išves panašų į šį tekstą:
Aktyvus aplankas: /home/tcltestuser/scripts

Beje, tokį pat rezultatą gautume viena komanda:
puts "Aktyvus aplankas: [pwd]"
tačiau ankstesniame pavyzdyje kintąmąjį aplankas galima panaudoti ir kitaip...

Operacijos su skaičiais

Su skaitinėmis reikšmėmis galima atlikti veiksmus. Tam skirta „komanda“ expr. Pavyzdyje pailiustruosime ir šios komandos „įdėtinį“ naudojimą, kai jos rezultatas panaudojamas kitoje expr komandoje:

set a [expr 3 + 6 ]
puts "Value: $a"

set a [expr [expr $a + 1 ] + 1 ]
puts "Value: $a"

Pateikiamas rezultatas:
Value: 9
Value: 11

Beje, nereikia tikėtis, kad Tcl atliks veiksmus juos nurodžius betarpiškai, pvz. priskyrimo komandoje. Tokiu atveju, tekstas bus priimtas kaip simbolių eilutė. Maža to, aplink aritmetinės operacijos, pvz., „+” ženklą palikus tarpus, netgi gausime klaidą, kaip yra pateikiamame pavyzdyje:

set a 3+6
puts "Value: $a"

set a 3 + 6
puts "Value: $a"

Gausime:

Value: 3+6
wrong # args: should be "set varName ?newValue?"
    while executing
"set a 3 + 6"
    (file "./pure.tcl" line 9)

Vis tik tai dar ne viskas – ir tai nėra absoliutus blogis, o savybė, kurią galima išmaniai išnaudoti. Mat expr „įvertina ir eilutės reikšmę. Tad, pateikiamame pavyzdyje, galime turėti kintamajui priskirti ir išraiškos reikšmę, ir paskaičiuoti jos reikšmę:

set e 21/7
puts "Value: $e"
puts [expr $e]

Atsakymas:
Value: 21/7
3

Išraiškose galima panaudoti keletą matematinių funkcijų. Kitame pavyzdyje pademonstruosime kvadratinę šaknį ir lošimų kauliuko „metimą“ panaudojant atsitiktinių skaičių generatorių.

set x 5
set S [expr sqrt($x) ]
puts "Šaknis: $S"

set K [expr [expr int([expr rand() * 6]) + 1] ]
puts "Kauliukas: $K"

Atsakymas (vienas iš galimų):
Šaknis: 2.2360679775
Kauliukas: 4

Sąrašai ir masyvai

Sąrašas yra dvi eilutės, kurios atskirtos tarpu (tiksliau, tuščia erdve), pvz., set listab "a b"
set listba {b a}

Kartais reikia turėti skiringus sąrašus, - turintį du elementus „a“ ir „b“ ir turintį vieną elementą „a b“. tai galima atlikti nurodant kabutę esant eilutės dalimi (naudojant \):
set singleitem "\"a b\""
tačiau tai vaizdžiau užsirašo panaudojus riestinius skliaustus:
set oneitem {{a b}}

Taip galima konstruoti sudėtingesnius sąrašus, pvz.:
set lists {a {b c} {xyz} d}
puts $lists

Kitas reikšmių grupavimo būdas yra masyvai, panašūs į hash masyvus perl kalboje. Kiekviena masyvo elementas turi priskirtą vardą, kuris nurodomas skliaustuose po masyvo vardo, pvz.,

set numbers("nulis") 0
set numbers("vienas") 1
set numbers("du") 2

set uid(0) root
set uid(1) daemon
set uid($numbers("du")) "test"

puts $uid(2)
puts $numbers("du")
puts $uid($numbers("vienas"))

Šis kodo fragmentas pateiks rezultatą:

test
2
daemon

Masyvo elementų kiekį galima sužinoti komanda array size masyvo_vardas, o sužinoti visus elementams priskirtus vardus – komanda komanda array names masyvo_vardas. Jų naudojimą iliustruosime pavyzdžiu:

puts "uid elementu kiekis: [array size uid]"
puts "Numeriai: [array names numbers]"

Atsakymas bus:

uid elementu kiekis: 3
Numeriai: {"du"} {"vienas"} {"nulis"}

Pastabos: 1) Daugiamačiai masyvai gali būti sukurti analogiškai, tik indeksus atskiriant kableliu, pvz.,
set dvinaris(1,"spalva") "raudona"
puts $dvinaris(1,"spalva")

2) Masyvus irgi galima perduoti procedūroms, tačiau ne taip paprastai kaip skaliarinius kintamuosius, nes reikia naudoti komandą upvar.

Veiksmai su simbolių eilutėmis

Iš ankstesnių aprašymų ir kai kurių pavyzdžių, jau pradėjote jausti, kaip dirbama su eilutėmis. Šiame skirsnelyje tą supratimą dar truputį pagilinsime.

Pirma, paminėsime, kad yra galimybės formatuoti pateikiamus duomenis (komanda format, bei „skenuoti“ eilutę pagal formatą, priskiriant reikšmes kintamiesiems (scan). Numatytos ir reguliariosios išraiškos (regexp)

Taip pat su eilutėmis galimos kai kurios operacijos (paminėsiu toli gražu ne visas):
string length – eilutės simbolių kiekis; string range – string first – string last –

Kadangi, labai dažna yra eilutės papildymo (prijungimo prie eilutės) operacija, tai įvesta netgi atskira komanda append.

Sąryšyje su eilutėmis, paminėsime ir kelias operacijas su sąrašais:
split - suskaidyti eilutę pagal visus nurodytus simbolius,
join - sujungti sąrašo elementus į eilutę,
lindex - gražinti sąrašo elemento reikšmę pagal nurodytą indeksą,
lrange - gražinti nurodyto intervalo sąrašo dalį,
llength - gražinti sąrašo elementų kiekį.

Visi minėti aspektai pademonstruoti šiame pavyzdyje:

#!/usr/bin/tclsh
set eilute "Darbas vakarais kvailį myli"

puts "Ilgis: [string length $eilute]"
puts "Pirmojo tarpo pozicija: [string first " " $eilute ]"
puts "Paskutinio tarpo pozicija:  [string last  " " $eilute ]"

# antro žodžio išpjovimas
puts [string range $eilute 7 14]

# "gražesnis" variantas antrojo žodžio pateikimui
set zodziai [split $eilute " "]
set antras [lindex $zodziai 1]
puts "Antrasis: \"$antras\"; viso žodžių: [llength $zodziai]"

# nuo antrojo žodžio iki pabaigos - du variantai
set a1 [string range $eilute [expr {[string first " " $eilute] + 1}] end]
set a2 [join [lrange $zodziai 1 end]]
puts "Pirmas variantas: $a1"
puts "Antras variantas: $a2"

append eilute " labiausiai"
puts $eilute

Ir rezultatai:

Ilgis: 27
Pirmojo tarpo pozicija: 6
Paskutinio tarpo pozicija:  22
vakarais
Antrasis: "vakarais"; viso žodžių: 4
Pirmas variantas: vakarais kvailį myli
Antras variantas: vakarais kvailį myli
Darbas vakarais kvailį myli labiausiai

Papildomos galimybės

Žinoma, kad Tcl kalba turi ir visą būtiną veikmų sekų valdymo komandų rinkinį: is, for, while, break, switch ir kitas, o taip pat procedūras, tačiau šįkart į tai nesigilinsime. Be kita ko, leidžiama iškviesti ir išorines (sistemos) komandas, o taip pat pateikiamos plačios galimybės darbui su failais. Bendram įsivaizdavimui, pateiksime vieną pavyzdį – patikrinimui, ar failas egzistuoja (pastaba: diezo ženklas # pradeda komentarą).

# Failo egzistavimo patikra
set FN "test.txt"
if { [file exists $FN] == 1} {
    puts "$FN egzistuoja! Šaliname jį!"
    send "rm $F\r"
}

Pastaba: ši patikra vyksta lokaliame kompiuteryje. Jei reikia patikrinti, ar failas egzistuoja nutolusiame serveryje (pvz., per FTP ar SFTP jungtį), reikia į ten siųsti patikros komandas - tačiau tai jau kitokio pobūdžio darbas, - ir šįkart šios temos neaptarsime.

Perkėlimas į kitą eilutę:

Komandos automatiškai nėra tęsiamos kitoje eilutėje. Tam reikia nurodyti „\“ eilutės gale. Simbolių eilutės kabutėse tęsiamos į kitą eilutę ir eilutės pabaigos simbolis įrašomas. Jei norime, kad eilutės galo simbolis būtų keičiamas tarpu, taip pat reikia panaudoti „\“, pvz.:
set viena_eilute "pirmas \
antras"

Nežinoma komanda

Kai Tcl bando vykdyti jam nežinomą komandą, iškviečiama unknown procedūra. Tai leidžia programiškai apdoroti šią situaciją. Panaudojimo pavyzdys:

#!/usr/bin/tclsh
proc unknown {args} { 
    puts "OHOHO nesuprantu: $args"
}

spausk kol dar gali pagal metus

expect – sulauk ir atlik!

„expect” yra Tcl išplėtimas, kurį, iš esmės, sudaro vos kelios komandos: expect, send, spawn ir interact.

Prieš kažko tikintis – pirmiausia reikia „išleisti“ interaktyvų „žvėrį“, pvz., telnet, ftp, sftp ar kt. Tai atlieka spawn komanda, kuri įkelia vykdymui kitą programą, kitaip vadinamą procesu. Šios komandos formatas:
spawn programa argumentai

Pvz.,
spawn ftp ftp.mozilla.org

Ši komanda „tyliai“ įkelia ir pradeda vykdyti ftp programą, prisijungiančią prie ftp.mozilla.org

Dabar ateina laikas žaidimas, tai yra, „pokalbiui“ su procesu. Jūsų programa tikisi, kad veikiantis procesas kažką „sako“, ir reaguojant į tą „kalbėjimą“, jūs jai irgi kažką „pasakote“. Vyksta pokalbis.

„expect“ komandos formatas:

expect 
  {pasakymo_šablonas1} {veiksmai1}
  {pasakymas_šablonas2} {veiksmai2}
   ...

Tai yra, jei programa pasakė kažką, kas tenkina šabloną, tada vykdomi veiksmai, susieti su tuo šablonu.

O jei reikia kažką „pasakyti“ procesui, naudojama send komanda, kurios formatas:
send -nustatymai eilutė

Tad ir mūsų pirmoji „Labas, pasauli“ programa gali būti perrašyta taip:

#!/usr/bin/expect
send "Labas, pasauli!\n"

Geriau „expect“ vietą, naudojimą ir paskirtį suprasite suprasite iš platesnio pavyzdžio.

SFTP prisijungimas

Šiame skyrelyje panaudosime expect, pailiustruodami SFTP automatizavimą. Tai supaprastintas kodas, pateikiamas tik kaip pavyzdys, kuris neperteikia visų subtilybių.

#!/usr/bin/expect

spawn sftp -o "ConnectTimeout=3" prisijungimo_vardas@SFTP_serveris

expect { "Password:" { send "$password\n"}
              "timed out" { close $spawn_id
                                     exit
                                 }
}
# Prisijungiame, paimame visus failus ir atsijungiame
expect "sftp>"
send "get *\r"
expect "sftp>"
send "bye\r"
expect eof

Ankstesnės "Advanced HTML" skyrelio temos:
Ateities kalbos?
Didžiųjų duomenų mitas
Unix komandinės eilutė
Pitonas, kandantis sau uodegą
AWK kalba - sena ir nuolat aktuali
Įvadas į Perl kalbą: Kas naudoja Perl?
Lambda išraiškos – Java į naują lygį
Dygios JavaScript eilutės
Sveikųjų skaičių žaidimai
Pelė uodega švystelėjo...
CGI.pm biblioteka: sausainiai
Kaip sužinoti ekrano charakteristikas?
Bilas Geitsas: kol dar nebuvo garsus
Vaizdi rašysena - VB Script
Programavimas Unix aplinkoje
Programavimo kalbų istorija
Ruby on Rails
JavaScript atspindžiai

JavaScript pradmenys
Tiesa apie REST
Lyginant su gimtąja kalba
Anotacijos Java kalboje
Viešojo rakto kriptografija
Programavimo kalbų klegesys
Java 8: Optional prieš null
Džonas Bakas – FORTRAN tėvas
Pirmoji programuotoja: Ada Lovelace
Perfokortos ir jų istorija
Kompiuterių ištakos
Tiesiog - Java
Vartiklis