\documentclass[12pt]{article}
\usepackage{a4wide}
\usepackage{epsfig}
\usepackage{czech}
%\usepackage{times}
% jsme v pdfTeXu?
\ifx\pdfoutput\undefined % nejsme v pdfTeXu
\else
\usepackage[citecolor=red,backref,bookmarks,
            pdfpagemode=None,
            pdftitle={Perl},
            pdfauthor={Michal Kocer},
            pdfkeywords={Nieder-Meier s.r.o.},
            pdfview=FitB]%
           {hyperref}
\fi  
%%%%%%%%%%%%%%%%%%%%%%
%%% Definice
\newcommand{\sfbf}{\bfseries\sffamily}
\newcommand{\HF}{\hspace*{\fill}}
%%%%%%%%%%%%%%%%%%%%%%
%%% Page layout
\textwidth= 170mm
\textheight= 255mm
\headsep=0pt
\topmargin= -15.5mm % -20.4mm
\oddsidemargin= -.5cm
\evensidemargin= -.5cm
%%%%%%%%%%%%%%%%%
\begin{document}%
%%%%%%%%%%%%%%%%%
\setcounter{page}{0}
\thispagestyle{empty}
%%%%%%%%%% Hlavicka
\begin{center}
  {\Large\bf Úvod do programovacího jazyka Perl\\}
  {\large Patrick M. Ryan \\
    {\small \texttt{patrick.m.ryan@gsfc.nasa.gov}}\\
    {\scriptsize listopad 1993}}
\end{center}
\tableofcontents
\newpage

%%%%%%%%%%%%%%%%%%%%%%
\parindent=0pt
\parskip=5pt
\tolerance=1000
%%%%%%%%%%%%%%%%%%%%%%

\section{Co je  Perl?}

Perl je programovacím jazykem primárně určeným jako pomůcka pro správu systému.
Kombinuje v~sobě prvky jazyka C, \texttt{awk}, \texttt{grep}u, \texttt{sed}u, a
Bourne shellu. Perl je výtečným nástrojem pro zpracování textu. Ačkoli je Perl
nazýván jazykem pro správu systému, lze jej bez problémů užívat i jinde,
například pro prototypy složitěějších programů a rozhodně všude tak, kde byl až
dosud užíván především skript psaný v~shellu.

Slovo \uv{Perl} je zkratkou odvozenou z~anglického \textit{Practical Extraction
  and Report Language}. Perl vytvořil a dále jej rozvýjí Larry Wall. Perl je
svobodně šířen pod GNU licencí a lze jej provozovat na většině užívaných
architektur a operačních sytémů; sem patří především celé spektrum užívaných
variant OS UNIX\footnote{UNIX je ochranná známka svého současného vlastníka}
dále VMS a dokonce i DOS a jeho nástupci.

Jak již bylo zmíněno, Perl se v~některých rysech podobá Bourne shellu,
\texttt{awk}, \texttt{sed}u, \texttt{grep}u a navíc umožňuje přistupovat
k~systémovým voláním a ke knihovním funkcím poskytovaných standardní knihovnou
jazyka C a tím zaplňuje prostor mezi shelovskými scripty a programy v~jazyce C.

Perl není kompilovaným jazykem, ale je rychlejší něž většina interpretovaných
jazyků. Před spuštěním je Perlovský skript nejprve načten programem
\texttt{perl} do paměti a jaksi předkompilován do rychlého vnitřního formátu.
Ve vetšině případů je perlovský skript rychleší než jeho analogie
naprogramovaná v~Bourne shellu. V~následujícím se na jazyk budeme odkazovat
slovem \textit{Perl} s~velkým P a na program \texttt{perl}, či na skript
napsaný v~Perlu, slovem \textit{perl} s~malým p.

Tento dokument neobsahuje vyčerpávající popis jazyka Perl. Daleko obsažnější
refence naleznete na konci tohoto článku.

\section{Základy syntaxe Perlu}

Perl je stejně jako jeho autor a celá myšlenka GNU velice volným a
svobodomyslným jazykem co se syntaxe týče. Jeho syntax sice vychází z~jazyka C,
ale obsahuje i některé rysy jiných programovacích jazyků.

Perlovské programy (skripty) jsou většinou ukládány v~souborech zakončených
\texttt{.pl}. Avšak tato přípona není povinná a většina scriptů na UNIXech je
spouštěna pomocí konstrukce \verb|#!|. Proto první řádek skript psaného v~Perlu
bývá (alepoň ve světě OS UNIX):

\noindent\verb|#!/usr/bin/perl -w|

V~Perlu musí být každý příkaz zakončen středníkem (\verb|;|).  Text, který
začíná znakem mřížka (\verb|#|) je považován za komentář a je ignorován.

Bloky kódu v~Perlu, např. v~podmíněných výrazech nebo smyčkách, je, narozdíl od
jazkyka C, \textit{vždy} potřeba uzavírat do složených závorek
(\verb|{|\dots\verb|}|).

\section{Základní datové typy}

Perl rozlišuje tři základní datové typy proměnných:
\begin{enumerate}
\item skalár
\item pole
\item asocialtivní pole (známé jako hashe)
\end{enumerate}

\subsection{Skaláry}

Skalár je základním datovým typem Perlu. Skalár může být celé číslo, číslo
s~pohyblivou řádovou čárkou nebo znakový řetězec. To, jaký druh skaláru  Perl
užije, se určuje na základě kontextu, ve kterém je ta která proměnná uvedena.
Jméno skalární proměnné začíná znakem dolar (\verb|$|). %$
Přiřazení řetězce do proměnné může vypadat takto:

\noindent\verb|$str = "hello world!";| %$

avšak v~žádném případě takto

\noindent\verb|str = "hello world!";|

V~Perlu je alfanumerický řetězec bez prefixu je obezně pokládán za řetězcový
literál. Proto druhý uvedený výraz značí přiřazení řetězcového literálu
\verb|"hello world!"| do řetězcového literálu \verb|"str"|.

Perlovský mechanismus užití uvozovek je obdobný mechanismu užívanému v~Bourne
shellu. Řetězce uzavřené do uvozovek (\verb|"|\dots\verb|"|) umožňují expanzi
proměných na jejich hodnoty a interpretují známým escape znak zpětné lomítko
((\verb|\|).V uvozovkách jsou hodnoty skalárních proměnných převáděny na
řetězec. Řetězce uzavřené do apostrofů (\verb|'|\dots\verb|'|) neprovádějí
žádnou expanzi proměnýých a znaků začínajících zpětným lomítkem, kromě
\verb|\'| a \verb|\\|.

Perlovské proměnné není nutné definovat předem. Proměnné jsou alokovány
dynamicky v~čase jejich použití. Je dokoce možné se odkazovat na neexistující
proměnné. V~numerickém kontextu neexistující proměnná hodnotu 0 a v~řetězcovém
kontextu hodnotu prázdného řetězce. Perl nabízí prostředky, kterými lze
rozlišit, zda se jedná o~neexistující proměnnou či existující proměnnou
s~nulovou hodnotou.

Perlovské proměnné jsou i tištěny a zpracovávány na základě kontextu. Proto
řětězcová proměnná, která obsahuje numerické znaky je interpolována
v~numerickém kontextu na numerickou hodnotu. Mějme následující fragmen kódu:

\begin{verbatim}
$x = 4;          # celé číslo
$y = "11";       # řetězec
$z = $x+$y;
print $z,"\n";
\end{verbatim}

Poté co je tento kód zpuštěn proměnná \verb|$z|%$
nabývá hodnoty 15.

Taková interpolace m;že probíhat i v~opačném směru. Číselné hodnoty jsou
v~řetězcovém kontextu formátovány na řetězce. Proto není třeba provádět nějaké
implicitní formátování jako v~jazyce C či FORTRAN. Tento typ konverze je
prováděn zejména při psaní na standardní výstup. Například:

\begin{verbatim}
$answer = 65;
print "the answer is $answer";
\end{verbatim}

Výstupem tohoto kódu bude \verb|the answer is 65|.
Proměnná \verb|$answer| %$
je konvertována  na řetězec \verb|"65"| a nikoli na znak s~ordinální hodnotou
65 (v~ASCII znak \verb|"A"|).

Číselné literály mohou být sopecifikovány některým z~běžných formátů
pro celá čísla nebo čísla s~pohyblivou řádovou  čárkou.
Celočíselné konstanty lze uvádět i v~oktalově či hexadecimálně:

\begin{verbatim}
$a = 12345         # celé číslo
$b = 12345.65      # číslo s pohyblivou řádovou čárkou
$c = 3.14E11       # scientific notation
$d = 0xABFF        # hexadecimálně
$e = 0377          # osmičkově
\end{verbatim}
%$

Řetězcové konstanty mohou být navíc užívány ve formě \textit{here document}
obdobně jako v~shellu.  Řetězcové konstanty tohoto typu začínají specifickým
řetězcem a pokračují až do chvíle dalšího výskytu tohoto řetězce.
Například v~následujícím příkladu se do proměnné \verb|$msg| %$
uloží předformátovaná víceřádková řetězcová zpráva:

\begin{verbatim}
$msg = <<_EOM_;
              *=======================================*
              | The system is going down. Log off now.|
              *=======================================*
_EOM_
\end{verbatim}


%$

\subsection{Skalární pole}

V~Perlovském scriptu lze používat pole (či seznamy) složené se skalárů.  Jméno
proměnné odkazující na pole skalárů obsahuje první znak zavináč (\verb|@|).
Kromě toho, že lze pole plnit prvek po prvku, lze pole naplnit naráz celé
seznamem jeho jednotlivých prvků, přičemž seznam je uzavřen do kulatých závorek
(\verb|(|\dots\verb|)|):

\begin{verbatim}
@numbers = (3,1,4,1,5,9);
@letters = ("this","is","a","test");
($word,$another.word) = ("one","two");
\end{verbatim}

Na jednotlivé prvky pole se odkazujeme pomocí indexů v~hranatých závorkách
(\verb|[|\dots\verb|]|), přičemž první prvek pole ma defaultně v~Perlu
index 0 (tuto hodnotu lze změnit):
\begin{verbatim}
$blah[2] = 2.718281828;
$message[12] = "core dumped\n";
\end{verbatim}

Všiměme si, že na prvek pole se odkazujeme jménem pole avšak s~prefixem
\verb|$| %$
(jde o~skalár) následovaným indexem v~hranatých závorkách.
Proto \verb|@pole| je jméno proměnné typu pole a \verb|$pole[0]| %$
je odkaz na první prvek tohoto pole.

Konstrukce \verb|$#| %$
následovaná jménem proměnné se užívá k~nalezení posledního platného indexu
pole. Proměnná \verb|$[| %$
obsahuje, případně nastavuje základní (nejnižší) možný použitelný index
proměnné typu pole. Defaultně ja tato proměnná nastavena, jak již bylo řečeno,
na hodnotu 0. Následující fragment kódu slouží pro zjištění délky pole:

\begin{verbatim}
# předpokládáme, že  @pole je pole nějakých zajímavých prvků
$n = $#pole - $[ + 1;
print "pole pole má $n prvků\n";
\end{verbatim}

Pole stejně jako proměnné jsou alokovány dynamicky prvek po prvku, čili jakmile
přiřadíme hodnotu do dalšího prvku pole. Pole lze alokovat předem tak, že
přiřadíme do proměnné \verb|$#|\textit{jméno\_pole} příslušnou hodnotu.
%$
\begin{verbatim}
$#months = 11; # pole @months má prvky o indexech  0..11
\end{verbatim}
%$

Perl nabízí velké množství nástrojů pro práci s~poli; nabízí prostředky pro
vkládání, vyjímání, přidání, rozdělení a slučování polí.

Perl umožňuje pracovat pouze s~jednorozměrnými poli. Vícerozměrná pole lze
však pomocí prostředků Perlu jednoduše napodobit.

\subsection{Asociativní skalární pole}

Asociativní pole (hash) je v~Perlu implementováno pomocí  rozptýlených tabulek.
Asociativní pole jsou asi nejužitečnějším risem jazyka Perl. Běžné aplikace
užívající asociativních polí  zahrnují například vytváření tabulek uživatelů
klíčované logovacím jménem  nebo vytváření tabulek jmen souborů.
Prefixem pro označení proměnné typu hash je znak procento (\verb|%|)

K~položkám asociativního pole se nepřistupuje přes číselné indexy jako u~pole
běžného, ale přes indexy (klíče) řetězcové (numerické klíče jsou převáděny na
řetězce). Asiciativní pole lze expicitně naplnit seznamem dvojic
\textit{položka--hodnota}. Například:
\
\begin{verbatim}
%quota = ("root",100000,
          "pat",256,
          "fiona",4000);
\end{verbatim}

K~položkám pole se přistupuje následujícím způsobem:

\begin{verbatim}
$quota{dave} = 3000;
\end{verbatim}
%$

V~tomto příkladě je \verb|dave| klíč (index) a \verb|3000| hodnota.
Všiměme si, že se v~tomto případě odkazujeme na položku, která je skalárem a
proto  jméno proměnné pole začíná znakem \verb|$|. % $

Dalším příkladem může být v~Perlu předdefinované pole \verb|%ENV|,
které obsahuje hodnoty proměnných prostředí. Klíčem pole je jméno proměnné
prostředí. Následuje kousek kódu, který zjistí zda pracujeme v~prostředí
X Window:
\begin{verbatim}
if ($ENV{DISPLAY}) {
  print  "Pravděpodobně pracujete v X Window\n"; 
}
\end{verbatim}
%$

V~Perlu mámě k~dispozici rutiny pro procházení  asociativními poli a pro mazání
prvků pole. Rutiny each, keys, values a delete.

Na tomto místě je vhodné poznamenat, že v~Perlu můžete pracovat bez konfliktu
se skalární proměnnou, polem, asiciativním polem, subrutinou a balíkem, které
budou mít všechny stejné jméno.

\section{Operátory}

Množina operátorů užívaných Perlem obsahuje téměř všechny operátory užívané
v~jazyce C. Všechny obviklé aritmetické operátory užívané v~C lze užít i v~Perlu.
V~následujícím seznamu jsou uvedeny operátory, které zná Perl oproti C navíc.
Popis jednotlivých operátorů je parafrázování textu z~excelentních manuálových
stránek Perlu:

\begin{center}
\begin{tabular}{|rp{13cm}|}
  \hline
  \verb|**|  & umocnění ( $x^3$ v~Perlu \verb|$x**3|)  \\ %$
  \verb|**=| & umocnění s~přiřazením \\
  \verb|()|  & prázdný seznam. Slouží k~vynulování pole. \\
  \verb|.|   & spojení dvou řetězců \\
  \verb|.=|  & spojení s~přiřazením  \\
  \verb|eq|  & srovnání shodnosti řetězců (\verb|==| je numerická rovnost).\\
  \verb|=~|  & vyhledání, substituce nebo nahrazení (defaultně v~řetězci \verb|$_|)\\ %$
  \verb|x|   & operátor opakování. Počet opakování uvádí pravý operand \\
  \verb|..|  & operátor rozsahu \\
  \verb|-f, -x, -l,|\dots & unární operátor pro testování souborů, obdoba příkazu \texttt{test(1)} \\
  \hline
\end{tabular}
\end{center}

Podrobnější popis operátorů naleznete v~manuálové stránce \verb|perlop(1)|.

\section{Implicitní argument}

Mnoho funkcí a syntaktických struktur v~Perlu užívá implicitních argumentů.
Ve většině případů je implicitním argumentem proměnná \verb|$_|.%$
Tato vlastnost Perlu je užitečná zejména pro pokročilé perlovské programátory
avšak činí kód perlu pro začátečníka téměř nečitelným. 

Proto raději všem nováčkům, kteří ještě nechápou jakým způsobem Perl pracuje
s~proměnnou \verb|$_|, %$
doporučujeme, aby všude uváděli argumenty funkcí a operátorů explicitně.
V~různých případech Perl zpracovává proměnnou \verb|$_| %$
jiným způsobem a většinou vše dosti podstatně závisí na kontextu.

Až budete mít za sebou několik obsáhlejších prográmků napsaných v~Perlu
tak se naopak neostýchejte imlicitních proměnných používat. Pak teprve budete
psát rychlé (a tajemně zašifrované) Perlovské kódy.

\section{Regulární výrazy}

Kdokoli jednou použil program \verb|grep| nebo \verb|expr| k~vykledání 
nebo porovnání řetězců bude jistě potěšen, že takové věci lze v~Perlu
implikovat přímo do kódu a tvoří tak další podstatný rys jazyka Perl.

\subsection{Speciální znaky v~regulárních výrazech}

Regulární výrazy v~Perlu mají obdobnou formu jako v~jazyce \verb|vi|.

\begin{center}
\begin{tabular}{rp{13cm}}
  \verb|.|   &  libovolný znak, kromě znaku nový řádek.\\
  \verb|+|   & alespoň jeden výskyt předchozího znaku.\\
  \verb|?|   & žádný nebo jeden výskyt předchozího znaku.\\
  \verb|*|   & žádný nebo více výskytů předchozího znaku.\\
  \verb|[...]|  & skupina znaků, vyhovat musí právě jeden.\\
  \verb|[^...]| & všechny znaky kromě uvedených v~závorkách.\\
  \verb|{N,M}|  & minimálně \verb|N| krát a maximálně \verb|M| krát opakování znaků.\\
  \verb|(...)|  & skupina znaků později použitelná jako jeden prvek \\
                &  (proměnná nebo \verb|\1| - \verb|\9|).\\
  \verb:(..|..|..): & jedna z~alternativ.\\
  \verb|\d|     & tj. \verb|[0-9]|\\
  \verb|\D|     & tj. \verb|[^0-9]| \\
  \verb|\w|     & tj. \verb|[a-zA-Z0-9_]|\\
  \verb|\W|     & tj. \verb|[^a-zA-Z0-9_]|\\
  \verb|\s|     & tj. \verb|[ \r\t\n\f]| (mezera,CR,tabelátor,LF,) \\
  \verb|\S|     & tj. \verb|[^ \r\t\n\f]|\\
  \verb|\1| - \verb|\9|  &   řetězec dříve nalezený uzavřený v~\verb|()|.\\
  \verb|\b|       & hranice slova \verb|\B| není hranice slova\\
  \verb|^|        & začátek řetězce\\ 
  \verb|$|        & konec řetězce\\ %$
  \verb|\n,\r,\f,\t|  &  mají svůj obvyklý význam\\
\end{tabular}
\end{center}

Syntaxe výrazu pro vyhledávání vzoru v~řetězci je
\verb|m/|\textit{vzor}\verb|/gio|, kde modifikátory mají nsáledující význam:
\verb|g| (global) globální prohledávání celého řetězce,
\verb|i| (ignore case) ignoruje se velikost znaků,
\verb|o| (only once) tento regulární výraz se kompiluje pouze jednou.
Spolu s~příkazem \verb|m| lze užít k~ohraničení argumentů libovolného páru
nealfanumerických znaků. Toto je velice užitečné, zejména tehdy,
hledáme-li v~řetězci jména souboru, které  obsahuje znak \verb|/|, například:
\begin{verbatim}
if (m!^/tmp_mnt!) {
    print "$_ is an automounted file system\n"; 
}
\end{verbatim} %$

V~případě, že \textit{vzor} je ohraničen znaky \verb|/| je uvedení
počátečního \verb|m| nepovinné.

Perl umožňuje i vyhledávání na více řádkách, vice se dočtete v~obsáhlejší
dokumentaci vyhledáte-li si odhaz na proměnnou \verb|$*|.%$

\subsection{Získání vyhledaného řetězce}
Obdobně jako ve \verb|vi|,  \verb|grep|u či  \verb|sed|u umožňuje Perl
další zpracování řetězce, který splňuje daný vzor regulárního výrazu.
Například následující kód emuluje UNIXový příkaz \verb|basename(1)|:
\begin{verbatim}
$file = "/auto/home/pat/c/utmpdmp.c";
($base) = ($file =~ m|.*/([^/]+)$|);
\end{verbatim} 
Výsledkem této části programu je hodnota \verb|utmpdmp.c| v~proměnné
\verb|$base|. %$
Kulaté závorky v~regulárním výrazu vymezují tu část vzoru, který chceme
extrahovat.

Návratová hodnota regulárního výrazu závisí na kontextu. V~kontextu pole,
výraz vrací pole řetězců, které splňují daný vzor. Ve skalárním kontextu
(většinou v~testu zda řetězec splňuje daný regulární výraz) výraz vrací
hodnotu 0 (ne) nebo 1 (ano). V~následujícím příkladu uvádíme použití skalárního
kontextu. Konstrukce \verb|<STDIN>| načte jeden řádek ze standardního vstupu
(detaily viz níže):
\begin{verbatim}

$response = <STDIN>;
if ($response =~ /^\s*y/i) {
      print "you said yes\n";
}
\end{verbatim}

Znovu připomínáme, že pro mnohé konstrukce v~Perlu je třeba rozlišovat skalární
kontext a kontext pole (seznamový kontext), jelikož jejich návratová hodnota
podstatnou měrou na tomto kontextu závisí.

\section{Řídící struktury}

Perl poskytuje všechny řídící struktury poskytované běžným procedurálním
jazykem a jak je u~Peerlu zvykem nabízí ještě některé další.

\subsection{\texttt{if-else}}

Perlovský příkaz \verb|if| má stejnou strukturu jako v~jazyce C. Perl používá i
stejné booleovské operátory jako C:\\
\begin{tabular}{rp{13cm}}
  \verb|&&|   &  logický součin (and)\\
  \verb.||.   &  logický součet (or)\\
  \verb.!.    &  negace (not)
\end{tabular}\\
Narozdíl od jazyka C neumožňuje Perl za podmínkovým výrazem\footnote{a to nejen
  u~příkazu \texttt{if}, ale i u~příkazů \texttt{unless, while, foreach}\dots}
uvézt pouze jeden příkaz, ale vyžaduje vždy užít příkazový blok. Tedy jinak
za podmínkovým výrazem musí být následné tělo vždy uzavřeno do složených
  závorek a to i v~případě, že se jedná pouze o~jediný příkaz.
Například v~tomuto kódu v~jazyce C:
\begin{verbatim}
if (error < 0)
  fprintf(stderr,"error code %d received"n",error);
\end{verbatim}
odpovídá v~Perlu:
\begin{verbatim}
if ($error < 0)
 { print STDERR "error code $error received\n"; }
\end{verbatim}

Perlovské analogie céčkovského \verb|if-else|  jsou \verb|else| a \verb|elsif|
a jejich použití je zřejmé.

Perl nabízí příkaz \verb|unless|, které obrací smysl podmínkového výrazu.
Například:
\begin{verbatim}
unless ($#ARGV > 0) # jestliže nemá script argument
  { print "error; no arguments specified\n"; exit 1; } # skonči 
\end{verbatim} %$

Perlovské pojetí pravdu je shodné s~pojetím v~jazyce C.
V~numerickém kontextu je nulová hodnoto považována za ``false'' a cokoli
nenulového za ``true''. Prázdný řetězec je považován za ``false'' a řetězec
délky větší než 1 za ``true''.  Pole a asociativní pole jsou považována
za ``true'' majíli alepoň  jeden prvek a za ``false'' v~případě. že jsou
prázdná. Neexistující proměnná je vždy ``false''.

Perl nemá obdobu řídící struktury \verb|case|, jelikož tato struktura lze
jednoduše nahradit jinými prostředky poskytovanými Perlem.

\subsection{Příkaz \texttt{while}}

Perlovský příkaz \texttt{while} je velice universální. Jelikož Perlovské
nazírání na pravdu je poměrně pružné může být jako podmínka
užito téměř cokoli. Například lze namísto podmínky užít, stejně jako v~C,
libovolný aritmnetický výraz, přiřazení či funkci.

Příkaz \verb|<STDIN>| bez argumentů znamená přiřazení jednoho řádku ze
standardního vstupu universální proměnné \verb|$_|. %$
\begin{verbatim}
while (<STDIN>) {
  print "na vstupu bylo: ",$_;
}
\end{verbatim} %$

Budeme-li se držet doporučené začátečnické praxe ohledně implicitních
parametrů bude kód vipadat takto:
\begin{verbatim}
while ( $_ = <STDIN>) {
  print "na vstupu bylo: ",$_;
}
\end{verbatim} 


Jak jsme uvedli výše, pole je \uv{pravdivé} v~případě, že mu zůstáva ještě
nějaký prvek. Například:
\begin{verbatim}
@users = ("nigel","david","derek","viv");

while (@users) {
   $user = shift @users;
   print "Uživatel $user má na tomto počítači uživatelský účet\n";
}
\end{verbatim}

Tato smyčka bude probíhat dokut bude v~poli \verb|@users| alespoň jeden prvek.
Rutina \verb|shift| vyjme první prvek z~pole a navrátí jeho hodnotu.

Pro předčasné ukončení smyčky užívá Perl dvou klíčových slov \verb|next| a
\verb|last|. Příkaz \verb|next| je obdoba příkazu \verb|continue| v~jazyce C,
tj.  smyčka ihned v~tomto místě programu pokračuje další iterací.  Příkaz
\verb|last| je analogií příkazu \verb|break| v~jazyce C, tj. smyčka se ukončí.

\subsection{Příkaz \texttt{for} a \texttt{foreach}}

Perlovské příkazy \verb|for| a \verb|foreach| jsou identické, tj. lze je
oba užít ve stejném významu v~libovolném kontextu.

Aby se věc ještě více zamotala, existují dva povolené způsoby syntaxe
těchto příkazů. První způsob je převzatý z~jazyka C:
\begin{verbatim}
@disks = ("/data1","/data2","/usr","/home");
for ($i=0; $i != $#disks; ++$i) {
     print $disks[$i],"\n";
}     
\end{verbatim}

Jakmile však jednou porozumíte způsobu jakým se v~Perlu pracuje s~poli
nebudete používat tuto céčkovskou, tříargumetovou, syntax.

Perl užívá syntax jednoargumentovou obdobně jako se užívá, například,
v~C-shellu. V~příkazu \verb|foreach| se jako argument uvede pole (seznam) a
příkaz postupně prochází toto pole prvek po prvku, avšak narozdíl od předchozí
demonstrace pomocí příkazu \verb|shift| nedojde k~destrukci pole.

Předchozí příklad můžeme přepsat, například, takto:
\begin{verbatim}
@disks = ("/data1","/data2","/usr","/home");
foreach(@disks) {
    print $_,"\n";
}    
\end{verbatim} %$

Ještě jenou připomeneme, že toto řešení je daleko elegantnější
a nevede k~destrukci pole \verb|@disks|. Je tomu tak proto, že
v~tomto případě proměnná \verb|$_| %$
není neobsahuje kopii hodnoty prvky pole, ale je jakýmsi ukazatelem na daný
prvek, proto veškeré změny prvedené na \verb|$_| %$
se projeví i na daném prvku pole.

\subsection{Příkaz \texttt{goto}}

Ano, je to tak i Perl obsahuje tolik zatracovaný příkaz \verb|goto|.
Příkaz \verb|goto|~\textit{label} přesměruje zpracovávání programu na
místo označené značkou \textit{label}. Avšak v~Perlu stejně jako všude jinde
platí: \textit{\uv{Pokud skutečně nemusíte  příkaz} \texttt{goto} \textit{nepoužívejte!}}


\section{Vestavěné funkce Perlu; knihovní a systémové funkce}

Perl obsahuje bohatou sadu vestavěných funkcí a umožňuje přístup
k~nejsužívanějším funkcím standardní knihovny jazyka C. Manuálové stránky
k~Perlu popisují dopodrobna všechny tyto funkce. My se v~tomto úvodu
omezíme pouze na několik nejčastěji používaných funkcí. Většina
těchto funkcí užívá implicitní proměnnou \verb|$_| %$
Kulaté závorky kolem argumentů funkcí, jsou většinou nepovinné.

\subsection{Vestavěné funkce}

\begin{description}
\item[\tt chop] \textit{výraz}  Odsekne poslední znak z~řetězce a tento znak
  vrátí. Taková funkce se může jevit ne moc zajímavá a užitečná dokud
  neporozumíme jak Perl pracuje se souborovým vstupem a výstupem.
  Při načítání řádku do proměnné Perl zachová i znak pro konec řádku \verb|\n|,
  což je velice výhodné při implementaci filterů, ale například pro
  interaktivní programy je tato vlastnost nežádoucí. Zde dobře poslouží
  funkce \verb|chop|.
\item[\tt defined] \textit{výraz}  Určuje zda výraz má či nemá hodnotu.
\item[\tt die] \textit{výrazy}  Vytiskne závěrečnou zprávu  a ukončí
  skript. Tato funkce se užívá v~případě, kdy se objeví nějaká zásadní chyba
  za běhu programu např., když  nelze otevřít soubor.
\item[\tt each] \textit{pole}  Navrací iterativním způsobem dvojice
  klíč-hodnota asociativního pole.
\item[\tt join] \textit{výraz,pole}  Spojí jednotlivé prvky \textit{pole}
  do jednoho řetězce, v~němž budou jednotlivé prvky odděleny hodnotami
  \textit{výraz}u.
\item[\tt pop] \textit{pole} Vyjme a vrátí poslední hodnotu pole, přičemž
  zkrátí pole. 
\item[\tt print] \textit{výraz} Vytiskne své argumenty. Více o~této funkci
  později.
\item[\tt push] \textit{pole,seznam} Pokládá pole za zásobník a uloží hodnoty
  uvedené v~seznamu na konec pole. 
\item[\tt shift] Vyjme první hodnotu s~pole, délku pole zkrátí o~1 a posune
  všechny prvky spměrem k~počátku pole. \texttt{shift} a \texttt{unshift}
  pracují obdobně jako \texttt{push} a \texttt{pop} s~tím rozdílem, že
  \texttt{shift} a \texttt{unshift} pracují nad počátkem  pole.
\item[\tt split(/{\it vzor}/,{\it výraz},{\it limit})] Rozdělí řetězec na
  jednotlivé prvky a tyto prvky navrátí jako pole. \textit{Vzor}
  určuje regulárním výrazem řetězec, který udděluje jednotlivé prvky.
  Běžným užitím této funkce je rozebrání řádků v~UNIXovém \texttt{/etc/passwd}
  na jednotlivé komponenty. Parametr \textit{limit} určuje maximum prvků, na
  které lze řetězec rozdělit.
\item[\tt substr] \textit{výraz,offset,délka} Vyjme podřetězec z~řetězce daného
  \textit{výraz}em a tento podřetězec vrátí. Podřetězec je vyňat z~řetězce
  počínaje na znaku \textit{offset} od počátku řetězce. Zaporný \textit{offset}
  určuje offset od konce řetězce. Parametr \textit{délka} určuje délku podřetězce.
\end{description}


\subsection{Funkce podobné UNIXovým příkazům}
\begin{description}
\item[\tt chmod] Změní přístupová práva k~uvedenám souborům.
\item[\tt chown] Změní vlastníka a skupinu uvedených souborů.
\item[\tt mkdir] Vytvoří adresáře.
\item[\tt unlink] Smaže soubor.
\item[\tt rename] Přejmenuje soubor.
\item[\tt rmdir] Smaže adresář.
\end{description}

\subsection{Knihovní funkce}
Perl umožňuje jednoduše používat velkou část knihovních funkcí jazyka C.
\begin{description}
\item[\tt getpw, getgr, \dots] Perl má přístup ke všem funkcím pracujících
  s~přístupovými právy, uživately, skupinamy, informacemi o~systému atd..
\item[\tt bind, connect, socket, \dots] Funkce pro meziprocesovou komunikaci
  (IPC); pro práci s~BSD sockety, FIFO, rourami atd.
\item[\tt stat] Informace o~přístupových právech k~danému souboru získané
  knihovní funkcí \verb|stat(2)|.
\item[\tt exit] Ukončí skript  s~určením návratového stavu.
\end{description}

\section{Spolupráce s~operačním systémem}
Systémové příkazy lze v~Perlu spouštět několika způsoby.

Perl buď může užít systémového volání \texttt{system(3)}. Daný řetězec je
předán k~spracování příkazovému interpretru (shellu).  Výstup prováděného
příkazu je poslán na standardní výstup. Návratový status provedého příkazu
je uložen v~proměnné \verb|$?|. %$

Dalším způsobem, který Perl umožňuje, je uzavřít systémový příkaz do
zpětných uvozovek (\verb|`|) obdobně jako je tomu v~shellu. Tento způsob se
užívá tehdy, kdý chceme odchytit výstup prováděného příkazu. Například
v~následujícím příkladě spustíme systémový příkaz \verb|hostname(1)|, jehož
výstup odchytíme do proměnné \verb|$host| %$ 
a funkcí \verb|chop| odřízneme nechtěný znak pro konec řádku:

\begin{verbatim}
$host = `hostname`; chop($host);
\end{verbatim}
I~v~tomto případě je návratový status uložen do proměnné \verb|$?|. %$

\section{Práce se soubory}
Perl poskytuje I/O funkce pro čtení a zápis prováděných nad textovými a
nad \uv{neformátovanými} soubory.

\subsection{Textový vstup a výstup}

Perl přistupoje k~souborů pomocí speciální proměnné ovladače souboru
(filehandle). Tyto proměnné je zvykem označovat velkými písmeny.

Soubory se otevírají pomocí funkce \verb|open|. Tato funkce má dva parametry:
ovladač souboru a jméno souboru.  Jméno souboru obvykle předcházejí
modifikátory. Jeden řádek souboru lze získat pomocí operátoru \verb|<>|, jehož
parametrem je obladač souboru: \texttt{<{\it ovladač\_souboru}>}.
Například:
\begin{verbatim}
open(F,"data.txt");
while($line = <F>) {
   # dělej ze vstupem něco zajímavého 
}
close F;
\end{verbatim} %$

Jménu souboru může předcházet modifikátor. Je-li modifikátorem znak
\verb|<| je soubor otevřen pro čtení (to je implicitní nastavení). Předchází-li
znak \verb|>| je soubor otevřen pro zápis. V~případě, že soubor již existuje
je jeho obsah přepsán novým obsahem. Nakonec je-li prefixem znak \verb|>>| je
soubor otevřen pro zápis, přičemž nově zapsaný text se připojuje existujícímu
obsahu souboru. Následuje několik příkladů:
\begin{verbatim}

# užití souboru /etc/passwd
open(PASSWD,"</etc/passwd");
while ($p = <PASSWD>) {
    chop $p;
    @fields= split(/:/,$p);
    print "Uživatel $fields[0] má domácí adresář $fields[5] \n";
}
close PASSWD;

# přidání informací do logového souboru
open(LOG,">>user.log");
print LOG "user $user logged in as root\n";

# přečte jeden řádek zadaný uživatelem
$response = <STDIN>;
\end{verbatim} %$

Perl má předdefinovány ovladače stadardního vstupu, výstupu a chybového
výstupu: \verb|STDIN|, \verb|STDOUT| a \verb|STDERR|.

Pokud se operátor \verb|<>| objeví v~kontextu pole jeho chování se změní.
Nevrátí pouze jeden řádek, ale pole řádků celého souboru.
Například:
\begin{verbatim}
$file = "nejaky.soubor";
open(F,$file);
@lines = <F>; # Nasaji celý soubor .. mňam, mňam,...
close F;
\end{verbatim}

Ačkoli je tato vlastnost  užitečná, je třeba užívat jí velice opatrně, jelikož
celý soubor je načten do operační paměti, která může být menší něž načítaný
soubor. Jelikož Perl užívá bufferovaných I/O operací není moc výhodné načítat
celé soubory kvůli urychlení perlovských skriptů.

\subsection{Roury}
V~Perlu lze užít funkci \verb|open| nejen k~načítání souborů, ale i~ke čtení
výstupů jiných procesů (systémových příkazů) nebo k~zápisu na standardní vstup
jiného programu, obdobně jako u~funkce jazyka C \verb|popen(3S)|.

Začíná-li v~argumentu funkce \verb|open| jméno souboru znakem roury (\verb.|.)
je jméno souboru považováno za systémový příkaz. Tento příkaz je spuštěn a na
jeho vstup lze posílat výstup ze skriptu, např. příkazem \verb|print|.

Je-li znak \verb.|. uveden na konci jména souboru, je tento řetězec považovaán
za systémový příkaz a je spuštěn. Jeho výstup lze poté číst operátorem
\verb|<>|.
\begin{verbatim}
open(MAIL," | mail root"); #  zaslání e-mailu administrátorovi
print MAIL "Tady se děje něco nekalého\n";
close MAIL; # a nyni je dopis odeslán

open(WHO,"who|"); # podíváme se, kdo je nalogován
while ($who = !WHO?) {
      chop $who;
      ($user,$tty,$junk) = split(/"s+/,$who,3);
      print "Uživatel $user je napojen  na  terminál $tty\n";
}
close(WHO);
\end{verbatim}

\subsection{Neformátované soubory}

Perlovské funkce \verb|sysread| a \verb|syswrite| umožňují
přímé čtení a zápis do souborů po bytech. Podprobnosti naleznete v~dokumentaci.

\subsection{Funkce {\tt print}}

Již jsem měli možnost vidět jak pracuje funkce \verb|print|. Popišme nyní
tento příkaz podrobněji.

Obecně, příkaz \verb|print| vezme řadu řetězců oddělených čárkou, provede
potřebné substituce hodnot proměnných a vytiskne výsledek. Spolu s~příkazem
\verb|print| se často užívá spojovací operátor (\verb|.|). Všechny náseldující
řádky kódu dávají stejný výsledek.

\begin{verbatim}
print "But these go to 11.\n";
$level = 11;
print "But these go to ",$level,".\n";
print "But these go to $level.\n";
printf "But these go to %d.\n",$level;
print "But these " . "go to " . $level . ".\n";
print join(' ',("But","these","go","to","$level.\n"));
\end{verbatim}

Jak jste jistě postřehli, máme v~Perlu k~dispozici i funkci \verb|printf|,
který se chová obdobně jako \verb|printf()| v~jazyce C.

Jak jsem viděli v~některém z~předchozích příkazů, funkce \verb|print|
může pracovat volotelným parametrem ovladače souboru, který se od dalších
argumentů \emph{neodděluje} čárkou.

\section{Poznámky o~kontextu pole}
V~jazyce C každý výraz vrací hodnotu. Tato hodnota může být vstupem
další funkce, aniž by byla potřeba nějaká dočasné proměnná.
Lze tedy psát, například, takovéto zápisy: \verb|chdir(getenv("HOME"))|

V~Perlu navrací mnohé funkce  pole. Tato výsledná pole se mohou stát vstupem
další funkce podobně tak, jak bylo popsáno výše. Tento přístup snižuje nutnost
zbytečných dočasných proměnných.

Následuje několik příkladů. První z~nich užívá funkci \verb|sort|, která
vrátí setříděné  pole, které je uvedeno jako argument.
\begin{verbatim}
@names = ("bill","hillary","chelsea","socks");
@sorted = sort @names;
foreach $name (@sorted) {
  print $name,"\n";
}
\end{verbatim}
Iteraci však můžeme provádět přímo na setříděném poli.
\begin{verbatim}
foreach $name (sort @names) {
  print $name,"\n";
}
\end{verbatim}
Další příklad ukazuje, že lze indexovat přímo navrácené pole:
\begin{verbatim}
$name = (getpwuid($<))[6];
print "Mé shutečné jméno je: ",$name,"\n";
\end{verbatim} %$

Funkce \verb|getpwuid| vrací pole, a  jelikož z~tohoto pole chceme
pouze položku označující skutečné jméno (GECOS) v~\verb|/etc/passwd| odkazujeme
se přímo na sedmý prvek navráceného pole (jsme v~kontextu pole) a tento prvek
ukládáme do proměnné \verb|$name|. %$

\section{Podprogramy a balíky (package)}

Perl umožňuje modulární programování tím, že poskytuje prostředky na
tvorbu podporgramů a knihoven.

\subsection{Podprogramy}

Perlovské skripty mohou užívat i uživatelem definované funkce, jež mají své
parametry a navracejí hondoty. Níže je uvedena kostra definice
takového podprogramu \verb|podprogram|.
\begin{verbatim}
sub podprogram {
  local($param1,$param2) ´@_;
  # dělej něco užitečného
  $hodnota
}
\end{verbatim} %$

Tento podprogram lze poté zavolat takto:
\begin{verbatim}
$return_val = do sub1("this is","a test");
\end{verbatim}
klíčové slovo \verb|do| lze nahradit znakem \verb|&|
\begin{verbatim}
$return_val = &sub1("this is","a test");
\end{verbatim}

Při psaní podporgramů je třeba mít na paměti několik věcí. Parametry jsou
uvnitř podporgramu uloženy v~poli \verb|@_|. Jelikož všechny proměnné jsou
implicitně globální, užili jsme funkci \verb|local()|, která specifikovala dané
proměnné jako lokální.

Perl obsahuje příkaz \verb|return|, kterým explicite definujeme návratovou
kondnotu funkce. Většinou se však \verb|return| neužívá, jelikož za návratovou
hodnotu podprogramu bere Perl hodnotu posledního provedeného výrazu. Proto,
chceme-li, aby podprogram navráti hodnotu 0, uvedeme  jako poslední řádek
podprogramu \verb|0;|.

\subsection{Packages}

Perl obsahuje knohovnu všech možných užitečných podprogramů a funkcí, které
lze do skriptu. Perlovská analogie k~céčkovskému \verb|#include| je
\verb|require|.

Například, Perl  má knihovnu pro prohledávání argumentů uvedených na
příkazovém řádku podobnou funkci  \verb|getopt(3)| v~jazyce C.

\begin{verbatim}
require 'getopts.pl';
&Getopts('vhi:');
if ($opt_v) {
  print "verbose mode is turned on\n";
}
\end{verbatim} %$

Samozřejmě, že je možné psát vlastní knihovny a moduly a tyto pak vkládat do
svých skriptů.

\section{Předdefinované proměnné}
Perl ovsahuje mnoho předdefinovaných proměnných, které jsou podorbně
dokumentovány v~manuálvých stránkách. Zde uvedeme jen ty nejužívanější.

\begin{description}
\item \verb|S_| Implicitní proměnná pro většinu funkcí a syntatických
  struktur.
\item \verb|$?| Stavové slovo navrácené posledním voláním systémového příkazu.
  Dolní bity obsahují informaci o~sygnálu, kterým byl příkaz ukončen. Horní
  bity obsahují informaci o~návratovém kódu. %$
\item \verb|$$| Číslo  procesu běžícího skryptu.
\item \verb|$<| UID uživatele, který skript spustil.
\item \verb|@ARGV| Paramtry skryptu z~příkazové řádky. Pozor, \verb|$ARGV[0]|
  je první skutečný argument a nikoli jméno skriptu, to jlze nalézt v~proměnné
  \verb|$0|;
\item \verb|%ENV| Asociativní pole, které obsahuje proměnné prostředí.
\end{description}
%$

\section*{Reference}
Knihy:
\begin{enumerate}
\item  Larry Wall \textit{Programming Perl}, O'Reilly (v~češtině  Computer Press)
\item  Randal Schwartz \textit{Learning Perl},  O'Reilly
\end{enumerate}

Online help a internet:
\begin{enumerate}
\item manuálové stránky 

\ifx\pdfoutput\undefined % nejsme v pdfTeXu
\item 
  \texttt{http://www.perl.com/CPAN} ---
  CPAN  -- FAQ,  Perl, příklady, moduly, knihovny,\dots
\item \verb|http://www.perl.com/|
\item newsgroup \texttt{comp.lang.perl}
\else
\item 
  \href{http://www.perl.com/CPAN}{htt://www.perl.com/CPAN/} ---
  CPAN  -- FAQ,  Perl, příklady, moduly, knihovny,\dots
\item \href{http://www.perl.com/}{http://www.perl.com/}
\item newsgroup \texttt{comp.lang.perl}
\fi
\end{enumerate}

%%%%%%%%%%%%%%%
\end{document}%
%%%%%%%%%%%%%%%


