Hlavní navigace

Perličky (1)

Lukáš Zapletal

Nový seriál nazvaný "Perličky" bude takovým nepravidelným ponořením do světa Perlu, který ke světu UNIXu (a samozřejmě Linuxu) neodmyslitelně patří. Budeme vám přinášet různé novinky a zprávy týkající se vývoje, ukázky užitečných skriptů a postupů a podobně. Doufám, že se mi podaří napsat alespoň jeden článek měsíčně.

Co je nového

Dnešní „novinky“ (dalo by se řící „stařenky“) začnu takovým krátkým poohlédnutím ve světě Perlu. A pěkně popořádku. Začneme klasicky. PERL znamená „Practical Extracting and Reporting Language“. Je to (rychlý) interpetovaný jazyk vyšší úrovně (garbage collector, uzávěry, eval ap.). Tento jazyk navrhnul, vyvinul (a vyvíjí) pan Larry Wall. Kdo dění okolo Perlu alespoň trošku sleduje, ví, co je Larry zač – je to takový „šoumen“. Na jedné nedávné konferenci o Perlu celou přednášku odrecitoval, na jiné zase odzpíval. Larry se zabývá jazyky (lingvistikou a podobně), a proto má Perl některé rysy přirozeného jazyka. Při jeho návrhu se na nic nevázal a s ničím nespěchal, nemusíte se tedy bát, že vaše aplikace za pár měsíců prostě nepoběží, protože se vyvinulo zcela nové zpětně nekompatibilní „API“, což mají některé komerční firmy ve zvyku a, dejme ruku na srdce, ony to dělat musí – kvůli zisku. Perl samotný je napsán v jazyce C, a jak Larry sám hlásá, ne proto, že C je přenositelné, ale proto, že C běží na mnoha platformách. Už samotná kompilace je toho důkazem: Perl nejprve zkompiluje tzv. miniperl interpret a zbytek kompilace jádra Perlu už běží pod taktovkou tohoto miniperlu. Také systémy CPAN a MakeMaker jsou důkazy obrovské přenositelnosti programů vytvořených v Perlu. Mimochodem, jádro Perlu (samostatně bez problémů použitelné) je velmi malé, několik stovek kilobajtů.

Základní ideou Perlu je, nikam programátora netlačit. Jak se v komunitě často říká: „There`s more than one way to do it“, zkráceně TMTOWTDI. Perl „sežere“ skoro vše. Pokud tedy nepíšete úplné bludy, interpret Perlu je spokojen (což můžete explicitně potačit). Začátečník může být zmaten, ale jakmile se přehoupnete přes základní problémy a Perlu alespoň trošku porozumíte, nebudete chtít nic jiného. Perl celý stojí jen na několika základních axiomech a je tak velmi rozšiřitelný. Když se dostalo do módy OOP, bylo do Perlu okamžitě elegantně (a bez větší námahy) přiděláno.

Aktuální verze je 5.6.X. Největší bombou v pět-šestce je podle mě podpora unicode. Perl umí s unicode řetězci nejen pracovat (načítat, porovnávat, třídít…), ale je možné psát zdrojový program v unicode, což má význam zejména u řetězcových konstant. Přibyla experimentální podpora přepracovaných vláken. Larry Wall kdysi dávno řekl, že bude moc šťastný, až Perl pojede na jeho handheldu, což se stalo realitou s touto verzí. Perl jde zkompilovat pro Palm OS. Pak už se jedná o kosmetické úpravy (podpora 64bitových platforem, soubory větší než 2GB, globální proměnné pomocí our…). Poslední věcí, o které bych se zmínil, je změna verzování Perlu. Až doposud se používalo pro číslo verze reálné číslo (daly se pak použít obyčejné číselné operátory např. k porovnání verzí ap.). Nyní se přešlo na typické verzování celými čísly oddělenými tečkami. Vývojová větev má druhé číslo liché, stabilní sudé (jako u jádra Linuxu).

V současné době komunita velmi aktivně připravuje návrhy (u návrhu Perlu se používá RFC dokumentů) na verzi 6, z nichž je zřejmé, jak se bude vývoj ubírat dále. Je jasné, že Perl čeká revoluce. Nejen proto, že kvůli zpětné kompatibilitě se staršími verzemi nemohou vývojáři syntaxi jazyka pozměnit tak, jak by si přáli, ale hlavně proto, že zdrojový kód Perlu je napsán v „hardcore C“ plném maker a neprůhledných konstrukcí, což velmi ztěžuje odhalování chyb. Proto bylo rozhodnuto, že Perl 6 bude úplně přepsán (něco podobného jako v projektu Netscape-Mozilla). Kompatibilita bude zajištěna pomocí zpětné dekompilace bytekódu, takže Perl 6 bude rozumět starším „pětkovým“ skriptům a programům (asi ne všem, ale lepší než drátem do oka :-). Larry Wall naznačil, že Perl 5.8 bude pravděpodobně poslední verzí řady 5.

V dalších dílech seriálu bych se vždy na úvod věnoval novinkám. Budou se týkat nejen celé komunity Perlu, ale také aktuálního dění okolo návrhu „šestky“. Nyní vzhůru na perličky.

„People say that Perl is hard to learn.
Uh! Japanese is hard to learn!“ – L. Wall

Proměnné

Předtím, než začneme s různými fintami s proměnnými, bych se pokusil shrnout jednotlivé elementy, kterými Perl disponuje. Základním stavebním kamenem je skalár, který může obsahovat libovolně dlouhý řetězec, číslo (celé resp. reálné), odkaz nebo nedefinovanou hodnotu (undef), a to právě tehdy, pokud neexistuje (zní to podivně, ale má to svůj smysl). Skalár se zapisuje s dolarem na začátku a řetězcové skaláry se před vyhodnocením převádějí na čísla (pokud to má smysl). Můžete tedy napsat:

$c = 5 + "5";

Při převádění řetězců Perl postupuje tak, že prohledává celý řetězec zleva, přeskočí případné bílé znaky (tabelátor, nový řádek, mezera…), dokud nenarazí na platné číslo. Věta „1.5 kg mouky smícháme s 2 vejci, přidáme sůl a za stálého míchání vlejeme do záchoda.“ by se převedla na číslo 1.5 (jedna celá pět – desetinná tečka). Vše funguje také obráceně, což znamená, že se čísla převedou na řetězce, pokud je toho třeba. Výjimku tvoří operátory (např. bitové operátory), které fungují pro řetězce a čísla odlišně. Abychom si vynutili číselné vyhodnocení, musíme přičíst nulu. V opačném případě stačí vloľit proměnnou do dvojitých uvozovek.

$a = "123";
$b = "456";
print $a & $b;          # vytiskne "002" - jako řetězce
print 0 + $a & 0 + $b;  # vytiskne "72" - až nyní jako čísla

To, že skalár začíná speciálním znakem, je výhoda. Můžete ho totiž použít v řezězci uvozeném dvojitými uvozovkami. Pokud Perl narazí na dvojité uvozovky, nahrazuje všechny tzv. speciální znaky. Většina (jako jsou \n či \") jsou podobné jako v jazyku C, ale Perl jich zná mnohem více. Podívejte se do vaší referenční přírůčky!

$tel = 0602000000;
print "Moje telefonní číslo je $tel\n";
# je ekvivalentní k
print "Moje telefonní číslo je " . $tel . "\n";

# avšak v jednoduchých uvozovkách Perl rozeznává pouze \' a \\
print 'Moje telefonní číslo je $tel\n';
# vypíše: Moje telefonní číslo je $tel\n

Někdy se ale stane, že ihned za proměnnou chceme v řetězci vypsat nějaký znak, který by však „splynul“ s názvem proměnné. Potom můžeme celou proměnnou zapsat do složených závorek:

($hod, $min) = (16, 45);
print "Je právě $hodh $minm\n";      # vypíše "Je právě"
print "Je právě ${hod}h ${min}m\n";  # oddělíme tedy název proměnné

Připomenu pouze, že znak „.“ (tečka) se používá ke spojování řetězců. Dalším elementárním prvkem je pole začínající znakem „@“. Indexuje se od nuly a je dynamické, tzn. můžete vesele přidávat a ubírat hodnoty a dále pak třídít, rozdělovat, spojovat (Perl disponuje velkým množstvím funkcí pro manipulaci s poli). Pole se inicializuje pomocí seznamu, o kterém si řekneme něco více příště. Stačí nám vědět, že seznam se zapisuje do kulatých závorek a jeho prvky od sebe oddělujeme čárkami. K jednotlivým prvkům přistupujeme pomocí hranatých závorek, a ty se pak chovají jako skaláry (také se pak píše „$“ narozdíl od „@“, který použijeme při manipulaci s celým polem). Pole naplňujeme skaláry, a přitom je jedno, jaký budou mít skaláry obsah (řetězec, číslo, odkaz…).

$skalar = 3;
@a = (1, "2", $skalar,);
print $a[0] + $a[1] + $a[2]; # vytiskne 6

# i když nyní změním třetí prvek
$a[3] = 0;
# skalár zůstane nezměněn
# (něco jiného by bylo, kdybych použil odkaz)

# vložím nyní na pozici 10 číslo 3.1415
$a[10] = 3.1415;
# pole @a má nyní 11 prvků (0 - 10) a
# prvky 3 - 9 jsou nedefinovány (hodnota undef)

# Perl tedy hlídá hranice pole, a to i "zleva"
$a[-1] = 2.1;
# změní poslední prvek pole

@b = @a; # kopie pole
@c = @a[1..2]; # kopie prvků 1 až 2
@d = @a[1,3]; # kopie prvků 1 a 3

Všimněte si poslední čárky v inicializaci pole @a, kterou jsem udělal záměrně. Perlu totiž nevadí, což je pro nás výhodné, pokud kopírujeme několik hodnot pod sebe (věčně musíme dávat pozor na poslední čárku). Pozor! Ačkoliv je možné si v jednom bloku kódu vytvořit skalár $a a pole @a (se stejným jménem), nedoporučuji to. Téměř jistě by tak vznikly nepříjemné chyby.

Posledním a nejmocnějším elementem je hash. Hash (nebudu překládat, v literatuře jako klíčované pole, asociativní pole [PPZ]) lze chápat jako pole, v němž jako klíč slouží řetězec znaků. Před proměnnou typu hash píšeme „%“ a k jednotlivým prvkům přistupujeme podobně jako u pole, ovšem za pomoci složených závorek. Hash můžete naplnit opět skaláry jakéhokoliv typu.

%vek = (
  "Lukas" => 21,
  "Petra" => 18,
  "Jirka" => "nutno zjistit",
  "Milan" => 99,
);

print $vek{"Lukas"} . "\n";

# díky tomu, že Perl se ke všem neznámým hodnotám chová, jako
# by to byly řetězce (jiné jazyky by pravděpodobně hlásily
# "neznámé klíčové slovo XY", nemusí se u klíčů dělat uvozovky
print $vek{Lukas} . "\n";

# což je ekvivalentní k
print "$vek{Lukas}\n";

Perl umožňuje vytvářet prakticky jakkoli velká pole a hashe. Pro vyhledávání jednotlivých klíčů v hashi používá velice rychlou metodu (myslím, že B-stromy – ale ruku bych za to do ohně nedal). Díky referencím můžete vytvořit jakoukoliv strukturu (seznam, zásobník, frontu, obousměrné seznamy…) a používáním hashů si velmi zjednodušíte život. Co všechno se s nimi dá dělat, si povíme příště.

Použitá literatura:
[PLD] Kolektiv autorů: Perl documentation, distribuce Perlu
[PPZ] P. Satrapa: Perl pro zelenáče Neokortex, ISBN 80–86330–02–8

Našli jste v článku chybu?