\usepackage[latin1]{inputenc}
\usepackage[italian]{babel}
\usepackage[T1]{fontenc}
\usepackage{times}
\usepackage{colortbl}
\usepackage{listings}
\usepackage{tikz}

\lstset{extendedchars,numbers=left,numberstyle=\tiny ,numbersep=5pt,language=Perl,showspaces=false,frame=single,framerule=0pt,backgroundcolor=\color{black!20},basicstyle=\small\ttfamily}

\mode<presentation>
{
\usetheme[hideothersubsections]{Goettingen}
\usecolortheme{beaver}
\usecolortheme{rose}
\setbeamertemplate{sections/subsections in toc}[ball]
}
\mode<article>{\usepackage{fullpage}}
\mode<handout>{\setbeamercolor{background canvas}{bg=black!5}}

\AtBeginSection[]{
  \begin{frame}<beamer>\frametitle{Argomenti}
  \small
    \tableofcontents[sectionstyle=show/hide,subsectionstyle=show/show/hide]
  \end{frame}
}

%% \AtBeginSubsection[]{
%%   \begin{frame}<beamer>{Argomenti}
%%     \tableofcontents[sectionstyle=show/hide,subsectionstyle=show/shaded/hide]
%%   \end{frame}
%% }

\newcommand{\Perl}{\textsf{Perl}}
\newcommand{\perl}{\texttt{perl}}

% 'sto coso non va... ed è pure copiato dalla documentazione di beamer!
%% \newenvironment{itemframe}
%% {\begin{frame}\frametitle{gino}\startitemframe}
%% {\stopitemframe\end{frame}}
%
%% \newcommand\startitemframe{\begin{itemize}}
%% \newcommand\stopitemframe{\end{itemize}}

\title{\Perl\ --- corso introduttivo}
\author[perl.it]{perl.it \url{http://www.perl.it/}}
\date[IPW2008]{Italian Perl Workshop 2008}

\begin{document}

\begin{frame}
\titlepage
\end{frame}

% shamelessly lifted from Llama3

\section{Introduzione}

\subsection{Informazioni generali}

\begin{frame}\frametitle{Cosa imparerete}
\begin{itemize}
\item a scrivere ed eseguire programmi Perl
\item a leggere molti semplici programmi altrui
\item a trovare ulteriori informazioni
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Cosa dovete già sapere}
\begin{itemize}
\item usare un editor di testi
\item usare la linea di comando
\item programmare in qualche linguaggio \uncover<2->{(anche se comincia per P)}
\end{itemize}
\end{frame}

\subsection{Cos'è Perl?} % ma perché non va con \textit???

\begin{frame}\frametitle{Il nome}
\begin{itemize}[<+->]
\item \Perl\ è il nome del linguaggio
\item \perl\ è il nome del programma
\item PERL è un errore
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Il nome}
\begin{itemize}[<+->]
\item \emph{non} è una sigla
\item è un nome
\item se proprio volete...
 \begin{itemize}[<+->]
 \item Practical Extraction and Report Language
 \item Pathologically Eclectic Rubbish Lister
 \item Polymorphic Existential Recursive Lambdas
 \end{itemize}
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Interprete o compilatore?}
\addtocounter{beamerpauses}{1}
\begin{description}
\item[Interprete] legge un'istruzione alla volta e la esegue
 \begin{itemize}[<+->]
 \item scova gli errori solo quando ci sbatte
 \item non fa ottimizzazioni serie
 \end{itemize}
\item[Compilatore] trasforma il programma da un linguaggio a un altro
 \begin{itemize}[<+->]
 \item può scovare molti errori staticamente
 \item può ottimizzare il codice
 \item \emph{non è mai sufficiente}
 \end{itemize}
\end{description}
\end{frame}

\begin{frame}\frametitle{Interpreti --- esempi}
\begin{itemize}[<+->]
\item la CPU è un interprete
\item \texttt{bash} è un interprete
\item la JVM è un interprete
\item \perl\ è un interprete
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Compilatori --- esempi}
\begin{itemize}[<+->]
\item \texttt{GCC} è un compilatore
\item \texttt{javac} è un compilatore
\item \perl\ è un compilatore
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Interprete \textit{e} compilatore}
\perl\ esamina l'intero programma, e se non ci sono errori lo
\emph{compila} in una struttura dati in RAM, la quale viene poi
\emph{interpretata}
\end{frame}

\begin{frame}\frametitle{La filosofia}
\begin{itemize}[<+->]
\item simile a un linguaggio naturale
\item TMTOWTDI
\item making easy things easy, and hard things possible
\item \emph{manipulexity} vs. \emph{whipuptitude}
\end{itemize}
\end{frame}

\subsection{Dove trovare \perl}

\begin{frame}\frametitle{Forse non serve}
\begin{itemize}
\item praticamente tutti i sistemi *NIX lo includono
\item pure il MacOS X
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Ma io uso Windows!}
\begin{overprint}
\onslide<1|handout:0>{Mi dispiace per te}
\onslide<2|handout:1>{\begin{itemize}
\item \url{http://win32.perl.org/}
\item \href{http://www.activestate.com/Products/activeperl/index.mhtml}{ActivePerl}, di ActiveState
\item \href{http://win32.perl.org/wiki/index.php?title=Strawberry_Perl}{Starwberry Perl}, se volete qualcosa di più ``normale''
\end{itemize}}
\end{overprint}
\end{frame}

\subsection{Scrivere ed eseguire programmi}

\begin{frame}\frametitle{File di testo}
\uncover<+->{Come la maggior parte dei linguaggi di programmazione,
Perl legge i programmi da semplici file di testo.}

\uncover<+->{Per il momento supponiamo di usare soltanto i caratteri
  dell'insieme ASCII (niente accentate)}

\uncover<+->{È più semplice se usate i fine-linea normali per la
  vostra piattaforma}
\end{frame}

\begin{frame}\frametitle{Convenzioni}
\begin{itemize}[<+->]
\item per i programmi potete usare i nomi che volete
\item certe volte si usa \texttt{.pl} come estensione
\item \texttt{\#!/usr/bin/perl} o \texttt{\#!/usr/bin/env perl}
\item i file che definiscono i moduli devono avere nomi particolari
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Esempio minimo}
\begin{lstlisting}
#!/usr/bin/env perl
use strict;
use warnings;

# qui il vostro programma
\end{lstlisting}
\end{frame}

\begin{frame}\frametitle{Esecuzione}
\begin{itemize}[<+->]
\item \texttt{perl nomefile}
\item *NIX: \texttt{chmod +x nomefile; ./nomefile}
\item Windows: trucchi con i file \texttt{.BAT}
\end{itemize}
\end{frame}

\section{Scalari}

\begin{frame}\frametitle{Cos'è uno scalare?}
\begin{itemize}
\item un singolo valore
\item \Perl\ distingue tra {\em singolare} e {\em plurale}
\item numeri e stringhe sono scalari
\end{itemize}
\end{frame}

\subsection{Numeri}

\begin{frame}\frametitle{Semantica dei numeri}
\begin{itemize}
\item i numeri sono trattati in intero o in virgola mobile, in modo trasparente
\item non è un problema vostro
\item<2-> a meno che non dobbiate preoccuparvi della precisione, ma per ora lasciate perdere
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Sintassi dei numeri}
\begin{itemize}
\item \lstinline!0!, \lstinline!-1!, \lstinline!1234645564!, \lstinline!1_234_645_564!
\item \lstinline!1.25!, \lstinline!-0.007!, \lstinline!1e12!, \lstinline!-3.5e-7!
\item \lstinline!0240!, \lstinline!0xA0!, \lstinline!0b10100000!
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Operazioni sui numeri}
\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!2+3!    & somma \\
\lstinline!5-7.5!  & differenza \\
\lstinline!4*12e3! & prodotto \\
\lstinline!7/3!    & quoziente \\
\lstinline!5%2!    & resto \\
\lstinline!3**7!   & esponente
\end{tabular}
\end{frame}

\begin{frame}[fragile]\frametitle{Confronto tra numeri}
\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!2 < 3!     & minore \\            
\lstinline!7.5 > 5!   & maggiore \\          
\lstinline/4 != 12e3/ & diverso \\           
\lstinline!3 <= 7!    & minore o uguale \\   
\lstinline!5 >= 2!    & maggiore o uguale \\ 
\lstinline!3 == 3!    & uguale
\end{tabular}
\end{frame}

\subsection{Stringhe}

\begin{frame}[fragile]\frametitle{Sintassi delle stringhe (1)}

Stringhe racchiuse tra virgolette singole:

\begin{itemize}
\item \lstinline!'gino'!
\item \lstinline!''!
\item \lstinline!'con l\'apostrofo'!
\item \lstinline!'su!\\
\lstinline!tre!\\
\lstinline!righe'!
\item \lstinline!'con \\ backslash'!
\item \lstinline!'backslash, poi n: \n'!
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Sintassi delle stringhe (2)}

Stringhe racchiuse tra virgolette doppie:

\begin{itemize}
\item \lstinline!"gino"!
\item \lstinline!"con \"virgolette\"..."!
\item \lstinline!"con \"a capo\" alla fine\n"!
\item \lstinline!"con\ttabulazioni"!
\item \lstinline!"multiple!\\
\lstinline!righe"!
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Operazioni sulle stringhe}
\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!'gino' . 'pino'! & concatenazione \\
\lstinline!'nano' x 7!      & ripetizione
\end{tabular}
\end{frame}

\begin{frame}[fragile]\frametitle{Confronto tra stringhe}
\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!'gino' lt 'pino'! & minore \\            
\lstinline!'nano' gt 'mano'! & maggiore \\          
\lstinline!'str1' ne 'str2'! & diverso \\           
\lstinline!'abcd' le 'wxyz'! & minore o uguale \\   
\lstinline!'piri' ge 'piri'! & maggiore o uguale \\ 
\lstinline!'buh' eq 'buh'!   & uguale
\end{tabular}
\end{frame}

\begin{frame}[fragile]\frametitle{Conversioni implicite}

\Perl\ converte tra numeri e stringhe a seconda di come vengono usati:

\begin{itemize}
\item \lstinline!'5'+3! \visible<2->{$\rightarrow$ \lstinline!8!}
\item \lstinline!4 x 5! \visible<2->{$\rightarrow$ \lstinline!'44444'!}
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Conversioni e avvertimenti}
\begin{itemize}
\item mettete {\em sempre} \lstinline!use warnings;! all'inizio dei vostri programmi
\item così, se scrivere \lstinline!'12gino'+3!, otterrete un messaggio di avvertimento:

\texttt{Argument "12gino" isn't numeric in addition (+)}
\end{itemize}

\visible<2->{Otterrete anche molti altri avvertimenti utili. Usate {\em sempre} \lstinline!use strict;use warnings;!}

\end{frame}

\subsection{Variabili scalari}

\begin{frame}[fragile]\frametitle{Nomi di variabile}
\begin{itemize}
\item i nomi di variabile scalare cominciano con \lstinline!$! %$
\item \lstinline!$gino! %$
\item \lstinline!$nome_1! %$
\item \lstinline!$ultima_riga_letta! %$
\end{itemize}

\visible<2->{Cercate di dare nomi sensati alle variabili. \lstinline!$a! {\em non} è un nome sensato. \lstinline!$prezzo! è meglio.}

\end{frame}

\begin{frame}[fragile]\frametitle{Assegnamento}
\begin{itemize}
\item \lstinline!$prezzo_finale = $prezzo * (1+$iva/100)!
\item \lstinline!$nome = 'gino'!
\item \lstinline!$totale += $prezzo_finale!
\item \lstinline!$nome .= ' ' . $cognome!
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Dichiarazioni}
\begin{lstlisting}
use strict;
use warnings;

my $a;my ($b,$c);
\end{lstlisting}
\end{frame}
%$

\subsection{Interpolazione}

\begin{frame}[fragile]\frametitle{Interpolazione}
Stringhe tra virgolette doppie {\em interpolano} le variabili:

\begin{itemize}
\item \lstinline!$quanti=12;$msg="Totale: $quanti pezzi"! \visible<2->{$\rightarrow$ \lstinline!Totale: 12 pezzi!}
\item \lstinline!$msg="Totale: \$quanti pezzi"! \visible<2->{$\rightarrow$ \lstinline!Totale: $quanti pezzi!}
\item \lstinline!$misura=7.5;$etichetta="${misura}cm"! \visible<2->{$\rightarrow$ \lstinline!7.5cm!}
\end{itemize}

Usate le graffe intorno al nome per evitare che i caratteri che seguono vengano interpretati come parte del nome.
\end{frame}

\subsection{Input/Output} % print, <>, chomp

\begin{frame}[fragile]\frametitle{Scrivere}
\begin{lstlisting}
print "Buh!\n";
my $a='qualcosa';print $a,"\n";
print "a","b","c";
\end{lstlisting}

\visible<2->{%
\lstinline/Buh!/\\
\lstinline!qualcosa!\\
\lstinline!abc!}
\end{frame}

\begin{frame}[fragile]\frametitle{Leggere}
\begin{lstlisting}
my $riga=<>; # legge una riga
\end{lstlisting}

\visible<2->{Il valore letto {\em include} il carattere di ``a capo''}
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{chomp}}
\begin{lstlisting}
my $riga=<>; # legge una riga, con \n alla fine
chomp($riga);
\end{lstlisting}

Adesso \lstinline!$riga! non contiene più il carattere di ``a capo''
\end{frame}

\subsection{\texttt{if} e \texttt{while}} % else, elsif

\begin{frame}[fragile]\frametitle{Esecuzione condizionale}
\begin{overprint}
\onslide<1|handout:0>
\begin{lstlisting}
if ($totale > $SOGLIA_SPEDIZIONE_GRATIS) {
   print "Spedizione: gratis\n"
}
\end{lstlisting}
\onslide<2|handout:0>
\begin{lstlisting}
if ($totale > $SOGLIA_SPEDIZIONE_GRATIS) {
   print "Spedizione: gratis\n"
}
else {
   print "Spedizione: costa\n";
}
\end{lstlisting}
\onslide<3|handout:1>
\begin{lstlisting}
if ($totale > $SOGLIA_SPEDIZIONE_GRATIS) {
   print "Spedizione: gratis\n"
}
elsif ($totale < $SOGLIA_MINIMA_ORDINE) {
   print "Compra di più!";
}
else {
   print "Spedizione: costa\n";
}
\end{lstlisting}
\end{overprint}
\end{frame}

\begin{frame}[fragile]\frametitle{Cicli condizionali}
\begin{lstlisting}
my $quanti=0;
while ($quanti < 10) {
  $quanti++;
  print "Siamo a $quanti\n";
}
\end{lstlisting}
\end{frame}

\subsection{Valori particolari} % undef, true/false, defined

\begin{frame}[fragile]\frametitle{\texttt{undef}}
\begin{itemize}
\item una variabile cui non è mai stato assegnato nulla ha valore \lstinline!undef!
\item \lstinline!undef! ha valore numerico \lstinline!0! e valore stringa \lstinline!''! (stringa vuota)
\item usare \lstinline!undef! in un'espressione genera un warning
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{defined}}
\begin{lstlisting}
my $a;
# fai qualcosa...

if (defined $a) { print "\$a non è definita\n" }
else { print "\$a ha valore «$a»\n" }
\end{lstlisting}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Vero e falso}
\begin{itemize}
\item i seguenti valori sono considerati {\em falsi}:
 \begin{itemize}
 \item \lstinline!0! (il numero zero)
 \item \lstinline!''! (la stringa vuota)
 \item \lstinline!'0'! (la stringa che contiene il singlo carattere ``cifra zero'')
 \item \lstinline!undef!
 \end{itemize}
\item tutti gli altri valori sono {\em veri}
\end{itemize}
\end{frame}

\section{Liste e Array}

\begin{frame}\frametitle{Cos'è un array?}
\begin{itemize}
\item una sequenza di valori {\em scalari}, indicati per posizione
\item \Perl\ distingue tra {\em singolare} e {\em plurale}
\item liste e array sono i plurali
\end{itemize}
\end{frame}

\subsection{Indici}

\begin{frame}[fragile]\frametitle{Indici normali}
Gli indici in un array cominciano da 0:

\begin{lstlisting}
$persone[0]="Cino";
$persone[1]="Dino";
$persone[2]="Gino";
$persone[3]="Lino";
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Uso}
Potete usare un ``accesso ad elemento di array'' ovunque usereste uno scalare.

\begin{lstlisting}
print $persone[0],"\n";
$totali[3]*=1.2;
\end{lstlisting}

Se usate un indice cui non avete mai assegnato nulla, il suo valore è \lstinline!undef!

\visible<2->{\textbf{Nota:} gli array si ``allungano'' implicitamente}
\end{frame}

\begin{frame}[fragile]\frametitle{Espressioni come indici}
L'indice può essere una qualsiasi espressione (purché abbia un valore
numerico).

\begin{lstlisting}
print $persone[$indice];
$totali[$numero_ordine 
        + $mese * $ordini_mese]
  = $totale_ordine;
\end{lstlisting}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Indici negativi}
Se usate un numero negativo come indice, accedete ``dal fondo'':

\begin{lstlisting}
$persone[0]="Cino";$persone[1]="Dino";
$persone[2]="Gino";$persone[3]="Lino";

print $persone[-1]; # stampa Lino
\end{lstlisting}

Gli array non si allungano ``all'indietro'': \lstinline!$persone[-10]!
genera un errore (ammesso che non ci siano 10 elementi)
\end{frame}

\begin{frame}[fragile]\frametitle{Ultimo indice}
\lstinline!$#persone! è l'ultimo indice valido per le \texttt{persone}:

\begin{lstlisting}
$persone[0]="Cino";$persone[1]="Dino";
$persone[2]="Gino";$persone[3]="Lino";

print $persone[-1]; # stampa Lino
print $persone[$#persone]; # stampa Lino
\end{lstlisting}
\end{frame}

\subsection{Valori}

\begin{frame}[fragile]\frametitle{Liste}
\begin{itemize}
\item \lstinline!(1, 2, 3)!
\item \lstinline!(1, 2, 3, )!
\item \lstinline!('a', 'b', 'c')!
\item \lstinline!(1, 'a')!
\item \lstinline!()!
\item \lstinline!(1..100)!
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{qw}}
\lstinline!qw! crea liste, da stringhe:
\ \\

\begin{overprint}
\onslide<1|handout:0>
\lstinline!qw(1 2 3)!\\
\lstinline!qw(a b c)!
\onslide<2|handout:0>
\lstinline!qw{1 2 3}!\\
\lstinline!qw{a b c}!
\onslide<3|handout:0>
\lstinline!qw/1 2 3/!\\
\lstinline!qw"a b c"!
\onslide<4|handout:1>
\lstinline!qw(1 2 3)!\\
\lstinline!qw{a b c}!\\
\lstinline!qw/1 2 3/!\\
\lstinline!qw"a b c"!

\end{overprint}
\ \\

\visible<4->{Potete usare i delimitatori che volete. \lstinline!qw! {\em non interpola}, nemmeno se usate le virgolette doppie come delimitatore.}
\end{frame}

\subsection{Assegnamento}

\begin{frame}[fragile]\frametitle{Assegnamento tra liste}
\begin{itemize}
\item \lstinline!my ($nome,$cognome) =!
\lstinline!    ('Gianni','Ceccarelli');!
\item \lstinline!($uno,$due)=($due,$uno)!
\item \lstinline!($p[0],$p[1])=qw(a b)!
\item \lstinline!my ($a,$b,$c)=(1,2)! \visible<2->{nota: \lstinline!$c! vale \lstinline!undef!}
\item \lstinline!my ($a,$b)=(1..10)! \visible<2->{8 valori ignorati}
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Variabili array}
\begin{lstlisting}
my @a=(1..10);
print $a[3],"\n";
\end{lstlisting}

\visible<2->{
\lstinline!4!
}

\visible<3->{Sì, \lstinline!@a! è il nome dell'intero array, ma l'accesso a elemento comincia con \lstinline!$!. Potete usare una variable array in ogni posto dove usereste una lista.}

\visible<4->{Una variabile array cui non è mai stato assegnato nulla ha valore \lstinline!()! (lista vuota).}
\end{frame}

\begin{frame}[fragile]\frametitle{Assegnamento, di nuovo}
\begin{lstlisting}
my @a=(1..10);
my @b=(20..29);
my @c=(100,99,@a,50,@b);
\end{lstlisting}

\visible<2->{È equivalente a \lstinline!@c=(100,99,1..10,50,20..29)!: gli array vengono appiattiti.}
\end{frame}

\subsection{Funzioni}

\begin{frame}[fragile]\frametitle{\texttt{pop} e \texttt{push}}
\begin{lstlisting}
my @a=1..5;    # 1 2 3 4 5
my $ultimo
  = pop @a;    # 1 2 3 4
push @a,11;    # 1 2 3 4 11
pop @a;        # 1 2 3 4
push @a,
  12,13,14;    # 1 2 3 4 12 13 14
\end{lstlisting}

\lstinline!pop! e \lstinline!push! agiscono sulla {\em coda} dell'array.
\end{frame}
%$

\begin{frame}[fragile]\frametitle{\texttt{shift} e \texttt{unshift}}
\begin{lstlisting}
my @a=1..5;    # 1 2 3 4 5
my $primo
  = shift @a;  # 2 3 4 5
unshift @a,11; # 11 2 3 4 5
shift @a;      # 2 3 4 5
unshift @a,
  12,13,14;    # 12 13 14 2 3 4 5
\end{lstlisting}

\lstinline!shift! e \lstinline!unshift! agiscono sulla {\em testa} dell'array.
\end{frame}
%$

\begin{frame}[fragile]\frametitle{\texttt{reverse}}
\begin{lstlisting}
my @a=(1..10);
my @b=reverse @a;
print @b;
\end{lstlisting}

\visible<2->{\lstinline!10987654321!}
\end{frame}

\subsection{Interpolazione}

\begin{frame}[fragile]\frametitle{Interpolazione}
Stringhe tra virgolette doppie {\em interpolano} le variabili, anche array:

\begin{itemize}
\item \lstinline!my @a=(1..3);$msg="Numeri: @a"! \visible<2->{$\rightarrow$ \lstinline!Numeri: 1 2 3!}
\item \lstinline!$email="dakkar@thenautilus.net"! \visible<2->{errore!}
\item \lstinline!$email="dakkar\@thenautilus.net"! \visible<2->{ok}
\item \lstinline!$email='dakkar@thenautilus.net'! \visible<2->{ok}
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Interpolazione di espressioni}
Si possono interpolare anche gli accessi ad elemento:

\begin{itemize}
\item \lstinline!my @a=(1..3);$msg="Numero: $a[1]"! \visible<2->{$\rightarrow$ \lstinline!Numero: 2!}
\item \lstinline!my $a=5;$msg="[boh]$a[1]"! \visible<2->{errore!}
\item \lstinline!my $a=5;$msg="[boh]${a}[1]"! \visible<2->{ok}
\end{itemize}
\end{frame}

\subsection{\texttt{foreach}}

\begin{frame}[fragile]\frametitle{Cicli su liste}
\begin{lstlisting}
foreach my $fratello (qw(Cino Dino Gino Lino)) {
  print "Un fratello si chiama $fratello\n";
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Assegnamenti nel ciclo}
\begin{lstlisting}
my @fratelli=qw(Cino Dino Gino Lino);
foreach my $fratello (@fratelli) {
  $fratello="<$fratello>";
}
\end{lstlisting}

Questo {\em cambia il valore} degli elementi dell'array \lstinline!@fratelli!.
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Assegnamenti nel ciclo}
\begin{lstlisting}
foreach my $fratello (qw(Cino Dino Gino Lino)) {
  $fratello="<$fratello>";
}
\end{lstlisting}

Questo {\em è un errore}.
\end{frame}
%$

\subsection{Il contesto}

\begin{frame}\frametitle{Contesto scalare e lista}
\begin{itemize}
\item ciascuna espressione in un programm \Perl\ viene valutata in un certo {\em contesto}
\item il contesto può essere {\em scalare} o {\em lista}
\item molte funzioni restituiscono risultati diversi a seconda del contesto
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Contesto scalare: esempi}
\begin{lstlisting}[escapeinside=«»]
$nome = «{\em \sffamily qualcosa}»;
$totali[3] = «{\em \sffamily qualcosa}»;
10 + «{\em \sffamily qualcosa}»;
«{\em \sffamily qualcosa}» + 10;
if («{\em \sffamily qualcosa}») { ... }
while («{\em \sffamily qualcosa}») { ... }
$persone[«{\em \sffamily qualcosa}»] = «{\em \sffamily qualcos'altro}»;
\end{lstlisting}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Contesto lista: esempi}
\begin{lstlisting}[escapeinside=«»]
@persone = «{\em \sffamily qualcosa}»;
($primo, $secondo) = «{\em \sffamily qualcosa}»;
($primo) = «{\em \sffamily qualcosa}»;
push @totali, «{\em \sffamily qualcosa}»;
print «{\em \sffamily qualcosa}»;
foreach my $nome («{\em \sffamily qualcosa}») { ... }
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Contesto scalare: casi particolari}
\begin{itemize}
\item un array in contesto scalare restituisce il numero di elementi: \lstinline!my @a=('a'..'z');my $c=@a;print $c! scrive \lstinline!26!
\item una {\em lista} in contesto scalare restituisce l'ultimo elemento (e spesso genera warning): \lstinline!my $a=qw(a b c);print $a! scrive \lstinline!c!
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Contesto lista: casi particolari}
\begin{itemize}
\item \lstinline!my @a=(1..10);@a=()! svuota l'array
\item \lstinline!my @a=(1..10);@a=undef! {\em non} svuota: \lstinline!@a! contiene un elemento, il cui valore è \lstinline!undef!
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Forzare il contesto}
\begin{lstlisting}
my @a;print scalar @a; # forza contesto scalare

# forza contesto lista, e assegna a scalare
my $lunghezza=()=funzione_lista();
\end{lstlisting}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Input in contesto lista}
\begin{lstlisting}
my @linee=<>;  # legge tutto l'input in memoria
chomp(@linee); # toglie tutti gli "a capo"
\end{lstlisting}

\visible<2->{{\em Non} fatelo se non siete sicuri che l'input sia piccolo}
\end{frame}


\section{Hash}

\begin{frame}\frametitle{Cos'è un hash?}
\begin{itemize}
\item una mappa tra {\em stringhe} e valori {\em scalari}
\item un po' come gli array, ma i singoli elementi sono indicati con una stringa (``chiave'') invece che con la loro posizione
\item gli hash non sono ordinati
\end{itemize}
\end{frame}

\subsection{Chiavi}

\begin{frame}[fragile]\frametitle{Accesso ad elemento}
\begin{itemize}
\item \lstinline!$altezza{'dakkar'}=1.72!
\item \lstinline!$altezza{$persona}=$altezza!
\end{itemize}

Il valore corrispondente a una chiave cui non è mai stato assegnato
nulla è \lstinline!undef!.
\end{frame}

\begin{frame}[fragile]\frametitle{Sintassi abbreviata per le chiavi}
\begin{itemize}
\item \lstinline!$altezza{'dakkar'}! e \lstinline!$altezza{dakkar}! indicano lo stesso elemento
\item se le cose tra \lstinline!{}! non sembrano essere un'espressione, sono trattate come una stringa
\item usate le virgolette in caso di dubbio
\end{itemize}
\end{frame}

\subsection{Valori}

\begin{frame}[fragile]\frametitle{Variabili hash}
\begin{itemize}
\item \lstinline!%altezza! indica l'intero hash
\item notare che \lstinline!$nome!, \lstinline!@nome! e \lstinline!%nome! sono variabili diverse %$
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Assegnamento a hash}
\begin{lstlisting}
my %traccia_in=('X','corso','Y','avanzati');

print "$traccia_in{X}\n";
\end{lstlisting}

\visible<2->{\lstinline!corso!

A un hash si assegna una lista chiave-valore. Notare che l'accesso a elemento di hash è interpolabile.}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Assegnamento a hash (2)}
\begin{lstlisting}
my %traccia_in=('X','corso',
                'Y','avanzati','Y','GUI');

print "$traccia_in{Y}\n";
\end{lstlisting}

\visible<2->{\lstinline!GUI!

Se una chiave appare più volte nella lista assegnata al hash, vale l'ultima.}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Hash come lista}
\begin{lstlisting}
my %traccia_in=('X','corso','Y','avanzati');
my @tracce=%traccia_in;

print "@tracce\n";
\end{lstlisting}

\visible<2->{\lstinline!Y avanzati X corso!

Notare che l'ordine è arbitrario: gli hash non sono ordinati.}
\end{frame}

\begin{frame}[fragile]\frametitle{Trasporre un hash}
\begin{lstlisting}
my %traccia_in=('X','corso','Y','avanzati');
my %stanza_per=reverse %traccia_in;

print "$stanza_per{avanzati}\n";
\end{lstlisting}

\visible<2->{\lstinline!Y!

Con \lstinline!reverse! trasformiamo la lista chiave-valore in una lista valore-chiave, per cui trasponiamo l'hash.

Se i valori in \lstinline!\%traccia_in! non fossero univoci, il valore di \lstinline!\%stanza_per! sarebbe mal definito.
}
\end{frame}
%$


\begin{frame}[fragile]\frametitle{Sintassi alternativa}
\begin{lstlisting}
my %traccia_in=( X => 'corso',
                 Y => 'avanzati');
\end{lstlisting}

\begin{itemize}
\item stesso valore di prima
\item \lstinline!=>! è come una virgola
\item ma quel che viene prima viene trattato come una stringa (a meno che non sembri un'espressione)
\end{itemize}
\end{frame}

\subsection{Funzioni}

\begin{frame}[fragile]\frametitle{\texttt{keys} e \texttt{values}}
\begin{itemize}
\item \lstinline!keys %a! restituisce la lista delle chiavi in \lstinline!%a!, {\em in un qualche ordine arbitrario}
\item \lstinline!values %a! restituisce la lista dei valori in \lstinline!%a!, {\em nello stesso ordine di \lstinline!keys!}
\item in contesto scalare, restituiscono il numero di chiavi (o valori, è lo stesso)
\item per sapere se un hash è vuoto o meno, invece di controllare \lstinline!keys %a!, basta controllare \lstinline!%a!: un hash è vero se e solo se è non-vuoto
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{each}}
\begin{lstlisting}
my %hash=( a => 1, b => 2, c => 3 );
while (my ($chiave,$valore) = each %hash) {
  print "Alla chiave $chiave",
        " corrisponde $valore\n";
}
\end{lstlisting}

\lstinline!each! visita l'hash in ordine arbitrario, restituendo ad ogni invocazione una nuova coppia chiave-valore; restituisce lista vuota (quindi un valore falso) alla fine.
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{exists} e \texttt{defined}}
\begin{itemize}
\item \lstinline!exists $hash{chiave}! restituisce vero se l'hash
contiene quella chiave (qualunque ne sia il valore)
\item \lstinline!defined $hash{chiave}! restituisce vero se il valore
corrispondente a quella chiave è definito (questo è il funzionamento
normale di \lstinline!defined!)
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Nota su esistenza etc.}
Notare la differenza:

\begin{lstlisting}
my %a=( vero => 1,
        falso => 0,
        non_definito => undef);
\end{lstlisting}

\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!$a{vero}!         & vero \\
\lstinline!$a{falso}!        & falso \\
\lstinline!$a{non_definito}! & falso \\
\lstinline!exists $a{non_definito}! & vero \\
\lstinline!defined $a{falso}! & vero \\
\lstinline!exists $a{non_ce}! & falso
\end{tabular}
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{delete}}
\begin{lstlisting}
my %hash=( a => 1, b => 2, c => 3 );
delete $hash{a};
if (!exists $hash{a}) {
  print "ok\n";
}
\end{lstlisting}

\lstinline!delete! elimina un elemento da un hash.
\end{frame}

\section{Subroutine}

\begin{frame}\frametitle{Cos'è una subroutine?}
\begin{itemize}
\item un blocco di codice riusabile
\item un blocco di codice parametrico
\item uno strumento per organizzare il codice
\end{itemize}
\end{frame}

\subsection{Definizione e invocazione}

\begin{frame}[fragile]\frametitle{Definire una sub}
\begin{lstlisting}
sub saluta {
  print "Ciao!\n";
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Invocare una sub}
\begin{lstlisting}
saluta();
\end{lstlisting}

\begin{itemize}
\item una volta, si usava \lstinline!&saluta()!; ma oggi si
preferisce evitare \lstinline!&!
\item \lstinline!&! prima del nome è necessario se il nome è lo stesso
di una funzione interna di \Perl: non fatelo
\item \lstinline!$nome!, \lstinline!@nome!, \lstinline!%nome!
e \lstinline!&nome! sono tutti diversi
\end{itemize}
\end{frame}
%$

\subsection{Argomenti e valore di ritorno}

\begin{frame}[fragile]\frametitle{Sub con parametri}
\begin{lstlisting}
sub saluta {
  print "Ciao $_[0]!\n";
}

saluta('Gianni');
\end{lstlisting} %$

Gli argomenti passati a una subroutine vengono visti
nell'array \lstinline!@_!.
\end{frame}

\begin{frame}[fragile]\frametitle{I parametri sono alias}
\begin{lstlisting}
sub azzera {
  $_[0]=0;
}

my $a=5;
azzera($a);
print $a;
\end{lstlisting} %$

Gli argomenti passati a una subroutine sono {\em
modificabili}. Stateci attenti!
\end{frame}

\begin{frame}[fragile]\frametitle{Idioma per i parametri}
\begin{lstlisting}
sub saluta {
  my ($nome)=@_;
  print "Ciao $nome!\n";
}

saluta('Gianni');
\end{lstlisting}

Di solito si copiano gli argomenti in apposite variabili, per evitare
problemi, e per dare dei nomi ai parametri.
\end{frame}

\begin{frame}[fragile]\frametitle{Valore di ritorno}
\begin{lstlisting}
sub somma {
  my ($primo,$secondo)=@_;
  return $primo+$secondo;
}

print somma(5,12);
\end{lstlisting}

\begin{itemize}
\item \lstinline!return! esce dalla subroutine, e restituisce il valore al
chiamante.
\item L'espressione a destra di \lstinline!return! viene valutata nello
stesso contesto in cui è stata invocata la subroutine.
\item \lstinline!return;! senza un'espressione
restituisce \lstinline!()! in contesto lista, e \lstinline!undef! in
contesto scalare
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Parametri variabili}
\begin{lstlisting}
sub somma_a_tutti {
  my ($quanto,@numeri)=@_;
  for my $numero (@numeri) {
    $numero+=$quanto;
  }
  return @numeri;
}

my @mesi=somma_a_tutti(30,1,-2,1,0,1,0,
                          1,1,0,1,0,1);
\end{lstlisting}

Notare che \lstinline!@numeri! si prende tutti gli argomenti dopo il
primo: se avessimo scritto \lstinline!my (@numeri,$quanto)=@_!,
\lstinline!$quanto! avrebbe sempre avuto il
valore \lstinline!undef!.
\end{frame}

\subsection{Variabili lessicali}

\begin{frame}[fragile]\frametitle{Che succede qui?}
\begin{lstlisting}
use strict;use warnings;
my $fuori=5;
sub prova {
  my ($param)=@_;my $dentro=7;
  return $param+$dentro+$fuori;
}
print "$param $dentro $fuori\n";
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Che succede qui?}
Eseguendo riceviamo degli errori:

\begin{verbatim}
Global symbol "$param" requires explicit
  package name at /tmp/tst.pl line 7.
Global symbol "$dentro" requires explicit
  package name at /tmp/tst.pl line 7.
Execution of /tmp/tst.pl aborted due to
  compilation errors.
\end{verbatim}
\end{frame}

\begin{frame}[fragile]\frametitle{Che succede qui?}
\begin{lstlisting}
use strict;use warnings;
my $fuori=5;
sub prova {
  my ($param)=@_;my $dentro=7;
  return $param+$dentro+$fuori;
}
print "$param $dentro $fuori\n";
\end{lstlisting}

Il motivo è che \lstinline!$param! e \lstinline!$dentro! sono
dichiarate all'interno del blocco della sub \lstinline!&prova!, e non
sono visibili all'esterno. \lstinline!$fuori!, invece, è visibile sia
fuori sia dentro. %$
\end{frame}

\section{Input/Output}

\subsection{Qualche dettaglio in più}

\begin{frame}[fragile]\frametitle{Scorrere l'input}
\begin{lstlisting}
use strict;use warnings;
my $righe;
while (my $riga=<>) {
 chomp($riga);print reverse($riga),"\n";
 ++$righe;
}
print "$righe\n";
\end{lstlisting}

\begin{itemize}
\item quel \lstinline!while! cicla su tutte le righe dell'input,
leggendone una alla volta
\item \lstinline!$righe! vale \lstinline!undef! all'inizio, ma %$
l'operatore di incremento lo trasforma in \lstinline!0! (senza
warning)
\item \lstinline!reverse! inverte anche le stringhe
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Scorrere l'input, versione brutta}
\begin{lstlisting}
use strict;use warnings;
my $righe;
for my $riga (<>) {
 chomp($riga);print reverse($riga),"\n";
 ++$righe;
}
print "$righe\n";
\end{lstlisting}

\begin{itemize}
\item fa quasi la stessa cosa di prima
\item ma ora carica tutto l'input in memoria
\item di solito non è una buona idea
\end{itemize}
\end{frame}

\subsection{Le magie di \texttt{<>}}

\begin{frame}[fragile]\frametitle{L'operatore \texttt{<>}}
\begin{itemize}[<+->]
\item \lstinline!<>! legge una riga (o tutte) dall'input
\item cos'è l'input?
\item normalmente è lo {\em standard input}
\item ma se vengono passati dei nomi di file al
programma, \lstinline!<>! apre quei file, uno dopo l'altro
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Esempio di parametri al programma}
\begin{lstlisting}
use strict;use warnings;
my $righe;
while (my $riga=<>) {
 chomp($riga);print reverse($riga),"\n";
 ++$righe;
}
print "$righe\n";
\end{lstlisting}

Se salviamo questo programma come \texttt{gira-file}, ed eseguiamo:

\begin{verbatim}
./gira-file uno.txt due.txt
\end{verbatim}

vedremo le righe di \texttt{uno.txt} invertite, seguite da quelle
di \texttt{due.txt} invertite, e infine il numero complessivo di
righe.
\end{frame}

\begin{frame}[fragile]\frametitle{Filehandle (anticipo)}
\begin{itemize}
\item se vogliamo leggere dallo standard input soltanto, possiamo
scrivere \lstinline!<STDIN>!
\item \lstinline!print! scrive normalmente sullo standard output
\item \lstinline!print STDERR 'qualcosa'! scrive sullo standard error
\item notare che manca la virgola!
\end{itemize}
\end{frame}

\section{Espressioni regolari}

\begin{frame}\frametitle{Cos'è un'espressione regolare?}
\begin{itemize}
\item evitiamo i tecnicismi
\item un'espressione regolare ({\em regex}) è un modo per descrivere
una famiglia di stringhe
\item si usano per verificare che una stringa appartenga a una certa
famiglia
\item ma anche per manipolare le stringhe
\end{itemize}
\end{frame}

\subsection{Casi semplici} % literal, simple charclass, repetition

\begin{frame}[fragile]\frametitle{Caso base}
\lstinline!gino! indica la famiglia di stringhe che contengono quei
quattro caratteri, consecutivi, in quell'ordine, in qualche punto
\end{frame}

\begin{frame}[fragile]\frametitle{Classi di caratteri}
\begin{itemize}
\item \lstinline![cdgl]ino! indica la famiglia di stringhe che contengono 
un carattere
tra \lstinline!c!, \lstinline!d!, \lstinline!g!, \lstinline!l!,
seguito da \lstinline!ino!
\item \lstinline!numero: [0-9]! indica la famiglia di stringhe che contengono 
\lstinline!numero: ! seguito da una cifra.
\item \lstinline![^cdgl]ino! indica la famiglia di stringhe che
contengono \lstinline!ino! preceduto da un carattere {\em non} tra
quelli
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Carattere qualsiasi}
\lstinline!a.b! indica la famiglia di stringhe che contengono 
\lstinline!a!, seguito da un carattere qualsiasi, seguito da \lstinline!b!.
\end{frame}

\begin{frame}[fragile]\frametitle{Ripetizione}
\begin{itemize}
\item \lstinline!a+! indica la famiglia di stringhe che contengono 
una sequenza di \lstinline!a!, lunga almeno 1 carattere.
\item \lstinline!ab*c! indica la famiglia di stringhe che contengono 
\lstinline!a!, seguito da una sequenza di \lstinline!b!, lunga anche
0, seguita da \lstinline!c!.
\item \lstinline!ab?c! indica la famiglia di stringhe che contengono 
\lstinline!a!, opzionamlente seguito da \lstinline!b!, seguito da \lstinline!c!.
\item Notare che \lstinline!a*! indica tutte le stringhe possibili (come
anche \lstinline!a?!, o la regex vuota)
\end{itemize}
\end{frame}

\subsection{Operatori più complessi} % anchors, parens

\begin{frame}[fragile]\frametitle{Alternanze}
\begin{itemize}
\item \lstinline!a|b|c! indica la famiglia di stringhe che
contengono \lstinline!a!, oppure \lstinline!b!, oppure \lstinline!c!
\item \lstinline!cane|gatto|topo! indica la famiglia di stringhe che
contengono \lstinline!cane!, oppure \lstinline!gatto!, oppure \lstinline!topo!
\end{itemize}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Ancoraggi}
\begin{itemize}
\item \lstinline!^a! indica la famiglia di stringhe che cominciano per \lstinline!a!
\item \lstinline!a$! indica la famiglia di stringhe che terminano per
\lstinline!a!
\end{itemize}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Parentesi}
\begin{itemize}
\item \lstinline!ab|c|de! indica la famiglia di stringhe che
contengono \lstinline!ab!, oppure \lstinline!c!, oppure \lstinline!de!
\item \lstinline!a(b|c|d)e! indica la famiglia di stringhe che
contengono \lstinline!abe!, oppure \lstinline!ace!,
oppure \lstinline!ade!
\item oltre a cambiare la precendenza, le parentesi indicano anche di
``segnarsi cosa è successo''
\end{itemize}
\end{frame}

\subsection{Uso generale} % m, s, split, =~, options, tr

\begin{frame}[fragile]\frametitle{Esempio: contare le pecore}
\begin{lstlisting}
use strict; use warnings;
my $pecore=0;
while (my $linea=<>) {
  if ($linea =~ m{pecora}) {
    ++$pecore;
  }
}
print "Ho visto $pecore pecore\n";
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{L'operatore \texttt{m//}}
\lstinline!$linea =~ m{pecora}!

\begin{itemize}
\item \lstinline!=~! indica di applicare l'operatore a destra sulla
stringa a sinistra
\item \lstinline!m{}! sta per {\em match}: restituisce vero se e solo
se la stringa appartiene alla famiglia descritta dalla regex
\item come \lstinline!qw!, anche \lstinline!m! può usare i
delimitatori che volete
\item si può scrivere anche \lstinline!//!, usando le barre e senza la 'm'
\item \lstinline/!~/ nega il risultato del match
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Esempio: sommare i numeri}
\begin{lstlisting}
use strict; use warnings;
my $totale=0;my $testo='';
while (my $linea=<>) {
  my ($prima,$numero,$dopo) =
    $linea =~ m{^([^0-9]*)([0-9]+)(.*)$};
  $totale += $numero;$testo.=$prima.$dopo;
}
print "Totale: $totale\n";
print "Testo: $testo\n";
\end{lstlisting}
\end{frame}
%$

\begin{frame}[fragile]\frametitle{L'operatore \texttt{m//} in contesto lista}
\lstinline!my ($prima,$numero,$dopo) =!
\lstinline!    $linea =~ m{^([^0-9]*)([0-9]+)(.*)$};!
%$

\begin{itemize}
\item \lstinline!m//! in contesto lista restituisce le parti della
stringa che corrispondono ai pezzi tra parentesi
\item se la stringa non corrisponde, restituisce la lista vuota
\item i pezzi sono anche disponibili nelle variabili speciali \lstinline!$1!,
\lstinline!$2!, ecc.
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Esempio: censurare gli indirizzi}
\begin{lstlisting}
use strict; use warnings;
while (my $linea=<>) {
  $linea =~ s{[a-z0-9.-]+\@[a-z0-9.-]+}
             {***\@***};
  print $linea;
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{L'operatore \texttt{s///}}
\begin{lstlisting}[escapeinside=«»,backgroundcolor=,numbers=none]
$linea =~ s{[a-z0-9.-]+\@[a-z0-9.-]+}{***\@***};

s/«{\em \sffamily regex}»/«{\em \sffamily stringa}»/
\end{lstlisting}

\begin{itemize}
\item l'operatore \lstinline!s///! prende il primo pezzo della stringa che
corrisponde alla regex, e lo sostituisce con la stringa suo parametro
\item notare i delimitatori, e il fatto che sia la regex sia la
stringa di sostituzione sono trattate come se avessero le virgolette doppie
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Esempio: leggere un CSV}
\begin{lstlisting}
use strict; use warnings;
while (my $linea=<>) {
  chomp($linea);
  my @campi = split /,/,$linea;
  for my $campo (@campi) {
    print "Campo: $campo\n"
  }
  print "-- fine record\n";
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{split}}
\begin{lstlisting}[escapeinside=«»,backgroundcolor=,numbers=none]
my @campi = split /,/,$linea;

split /«{\em \sffamily regex}»/, «{\em \sffamily stringa}»
\end{lstlisting}

\begin{itemize}
\item l'operatore \lstinline!split! spezza la stringa nei punti
corrispondenti alla regex
\item \lstinline!join !{\em \sffamily stringa}\lstinline!, !{\em \sffamily lista} fa l'operazione ``inversa'' (ma con i separatori tutti uguali)
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Opzioni per le regex}
\begin{lstlisting}[escapeinside=«»,backgroundcolor=,numbers=none]
m/«{\em \sffamily regex}»/smxi
s/«{\em \sffamily regex}»/«{\em \sffamily stringa}»/smxig
\end{lstlisting}

\begin{itemize}
\item \verb!/s! fa in modo che \lstinline!.! corrisponda anche al
carattere di ``a capo''
\item \verb!/m! fa in modo che \lstinline!^! e \lstinline!$!
corrispondano all'inizo e alla fine di ciascuna riga (\lstinline!\A!
e \lstinline!\z! corrispondono sempre a inizio e fine {\em
stringa}) %$
\item \verb!/x! ignora gli spazi nella regex, per aumentare la
leggibilità (mettete una \lstinline!\! davanti agli spazi che devono
esserci)
\item \verb!/i! fa in modo che maiuscole e minuscole non vengano distinte
\item \verb!/g! fa in modo che la sostituzione avvenga in tutti i
punti che corrispondono alla regex, non solo il primo
\end{itemize}
\end{frame}

\section{Controllo del flusso}

\begin{frame}[fragile]\frametitle{Strutture di controllo}
Abbiamo visto \lstinline{if}:
\begin{lstlisting}
if ($totale < 0) { print "Eh?\n" }
\end{lstlisting}

E abbiamo visto \lstinline!while!:
\begin{lstlisting}
while (<> !~ /^[sn]/) {
 print "Rispondi sì o no\n"
}
\end{lstlisting}
\end{frame}
%$

\subsection{Controlli negati} % unless, until

\begin{frame}[fragile]\frametitle{Controlli negati}
Il contrario di \lstinline{if} è \lstinline!unless!:
\begin{lstlisting}
unless ($totale >= 0) { print "Eh?\n" }
\end{lstlisting}

Il contrario di \lstinline!while! è \lstinline!until!:
\begin{lstlisting}
until (<> =~ /^[sn]/) {
 print "Rispondi sì o no\n"
}
\end{lstlisting}
\end{frame}
%$

\subsection{Modificatori}

\begin{frame}[fragile]\frametitle{Modificatori}
Le strutture di controllo di flusso possono essere scritte anche in un altro modo:

\begin{lstlisting}
print "Eh?\n" if $totale < 0;
print "Eh?\n" unless $totale >= 0;
print "Rispondi sì o no\n" while <> !~ /^[sn]/;
print "Rispondi sì o no\n" until <> =~ /^[sn]/;
\end{lstlisting}

Possono modificare solo una istruzione, non un blocco.
\end{frame}

\subsection{\texttt{for}}

\begin{frame}[fragile]\frametitle{\texttt{for}}
Per i nostargici del C:
\begin{lstlisting}
for (my $i=0;$i<@array;++$i) {
 print "\$array[$i] -> $array[$i]\n";
}
\end{lstlisting}

Si usa piuttosto di rado.
\end{frame}

\subsection{Controllo dei cicli}

\begin{frame}[fragile]\frametitle{Uscire dal ciclo}
\begin{lstlisting}
while (my $line=<>) {
 chomp($line);
 last if $line =~ /^exit$/i;
 run_command($line);
}
\end{lstlisting}
%$
\end{frame}

\begin{frame}[fragile]\frametitle{Saltare un'iterazione}
\begin{lstlisting}
while (my $line=<>) {
 chomp($line);
 next if $line =~ /^\s*#/;
 last if $line =~ /^exit$/i;
 run_command($line);
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Ripetere un'iterazione}
\begin{lstlisting}
for my $parola (@parole) {
 pronuncia($parola);
 my $tentativo=<>;chomp($tentativo);
 if ($tentativo eq $parola) {
  print "Bravo!\n";
 }
 else {
  print "No, rirprova\n";
  redo;
 }
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Iterazioni annidate}
\begin{lstlisting}
LINEA: while (my $linea=<>) {
  chomp($linea);
  my (@parole)=split /\s+/,$linea;
  for my $parola (@parole) {
    next LINEA if $parola eq '--';
    usa_parola($parola);
  }
}
\end{lstlisting}
\end{frame}

\section{Moduli}

\subsection{Cosa sono}

\begin{frame}\frametitle{Cos'è un modulo?}
\begin{itemize}
\item un insieme di funzioni riusabili
\item un insieme di funzionalità riusabili
\item un'estensione del linguaggio
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Qualche modulo utilissimo}
\begin{itemize}
\item \lstinline!DBI! per accedere ai database
\item \lstinline!CGI! per scrivere CGI
\item \lstinline!LWP! per accedere al web
\item \lstinline!HTML::Parser! per manipolare HTML
\item \lstinline!XML::LibXML! per manipolare XML
\item \lstinline!Template! per generare testo da modelli e dati
\item \lstinline!Getopt::Long! per le opzioni a riga di comando
\item \lstinline!DateTime! per manipolare date
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Come si scrive un modulo?}
Non ve lo dico.

\visible<2->{No, seriamente: questo è un corso introduttivo. Scrivere moduli è un argomento abbastanza avanzato.}
\end{frame}

\begin{frame}[fragile]\frametitle{Come si usa un modulo?}
\begin{lstlisting}
use strict; use warnings;
use Cwd;

print 'La directory corrente è: ',cwd(),"\n";
\end{lstlisting}

\lstinline!use! importa un modulo, e permette di usarne le funzioni.
\end{frame}


\begin{frame}\frametitle{Come dovete usare i moduli}
\begin{itemize}
\item scoprite cosa vi serve
\item trovate il modulo giusto
\item installatelo
\item studiate la documentazione
\item scrivete il vostro programma
\end{itemize}
\end{frame}

\subsection{CPAN}

\begin{frame}\frametitle{Dove stanno i moduli?}

CPAN

\begin{itemize}
\item Comprehensive Perl Archive Network
\item decine di miglialia di distribuzioni
\item tutte testate e documentate
\item non proprio tutte utili\ldots
\item \url{http://www.cpan.org/}
\item \url{http://search.cpan.org/}
\end{itemize}
\end{frame}

\subsection{Installazione} % CPAN.pm, distribuzioni e local::lib

\begin{frame}[fragile]\frametitle{\texttt{CPAN.pm}}
\texttt{\$ perl -MCPAN -e shell} (o \texttt{\$ cpan})
\begin{semiverbatim}
cpan shell
cpan> \textbf{install The::Module}
\end{semiverbatim}

Questo scarica, testa, e installa il modulo che avete chiesto. Notare che alcuni moduli possono richiedere un compilatore C.

{\footnotesize \texttt{CPAN.pm} può richiedere un po' di configurazione, la prima volta che lo eseguite}
\end{frame}

\begin{frame}\frametitle{Ma io non sono \texttt{root}!}
\texttt{CPAN.pm}, di solito, installa i moduli nelle directory di sistema.

Se non avete i poteri di amministratore, questo è un problema.

Il modulo \texttt{local::lib} semplifica il procedimento per installare moduli nella vostra {\em home directory}.

Seguite {\em con molta attenzione} le sue istruzioni di installazione.
\end{frame}

\subsection{Cenni di OOP}

\begin{frame}[fragile]\frametitle{Cenni di OOP} % -> notation, new
\begin{itemize}
\item \Perl\ ha un supporto per la programmazione a oggetti
\item {\em non} scendiamo nei dettagli
\item solo due cose:
 \begin{itemize}
 \item \lstinline!$oggetto->metodo(@parametri)!
 \item \lstinline!my $oggetto = Classe->new(@parametri)!
 \end{itemize}
\end{itemize}
\end{frame}

\section{Filehandle}

\begin{frame}\frametitle{Cos'è un filehandle?}
\begin{itemize}
\item un filehandle è l'oggetto tramite cui si leggono e scrivono file in Perl
\item abbiamo già visto \texttt{STDIN}, \texttt{STDOUT} e \texttt{STDERR}
\end{itemize}
\end{frame}

\subsection{Leggere e scrivere file}

\begin{frame}[fragile]\frametitle{Apertura di un file}
\begin{lstlisting}
uso strict; use warnings;
# facciamo finta che le variabili coi nomi
# siano definite da qualche parte
open my $config,'<',$nome_file_config;
open my $output,'>',$nome_file_output;
open my $log,'>>',$nome_file_log;
\end{lstlisting}

\lstinline!$config! viene aperto in lettura, \lstinline!$output! in scrittura, e \lstinline!$log! in ``append''. %$
\end{frame}

\begin{frame}[fragile]\frametitle{Leggere da filehandle}
{\footnotesize continua dal programma precendente}

\begin{lstlisting}
my %conf;
while (my $line=<$config>) {
 chomp($line);
 next if $line =~ m{^\s*#};
 my ($key,$val)=split /=/,$line;
 $conf{$key}=$val;
}
\end{lstlisting}

Leggere da un filehandle si fa sempre nello stesso modo, comunque sia stato ottenuto il filehandle.
\end{frame}

\begin{frame}[fragile]\frametitle{Scrivere su filehandle}
{\footnotesize continua dal programma precendente}

\begin{lstlisting}
print $log "Letta configurazione\n";
for my $key (keys %conf) {
  print $output "$key -> $conf{$key}\n";
}
print $log "Stampata configurazione\n";
\end{lstlisting}
%$

Scrivere su un filehandle si fa sempre nello stesso modo, comunque sia stato ottenuto il filehandle.
\end{frame}

\begin{frame}[fragile]\frametitle{Scrivere su filehandle}
{\footnotesize continua dal programma precendente}

\begin{lstlisting}
close $config;close $output;close $log;
\end{lstlisting}
%$
\end{frame}

\begin{frame}[fragile]\frametitle{Gestire gli errori}
\begin{lstlisting}
unless (open my $fh,'<',$nome) {
  die "Errore nell'apertura di $nome: $!";
}
\end{lstlisting}

\lstinline!die! esce dal programma stampando un errore. \lstinline/$!/ è la versione ``leggibile'' dell'errore dato dal sistema operativo (\texttt{strerror(errno)}, per chi pensa in C). %$
\end{frame}

\subsection{Codifiche} % binmode e use utf8 e use encoding

\begin{frame}\frametitle{Non mi funzionano le accentate!}
\begin{itemize}
\item se avete provato qualcuno dei programmi di esempio, potreste aver notato grossi problemi con le lettere accentate
\item dipende tutto dalla codifica dei caratteri
\item evito di entrare nei dettagli, richiederebbe ore
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Linee guida per le codifiche}
\begin{itemize}
\item quando leggete testo da un filehandle, tenete conto della codifica, e traducete in rappresentazione interna
\item quando scrivete testo su un filehandle, fate l'operazione inversa
\item dichiarate la codifica del sorgente del programma
\item non preoccupatevi delle codifiche finché lavorate con i dati interni al programma
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Qualcosa del genere}
\begin{lstlisting}
use strict;use warnings;
use utf8;
use open ':std',':locale';
\end{lstlisting}

\begin{itemize}
\item \lstinline!use utf8! dichiara che {\em il sorgente} è codificato in UTF-8
\item usate \lstinline!use encoding 'iso-8859-1'! se salvate in quell'altra codifica
\item \lstinline!use open ':std',':locale'! fa in modo che tutti i filehandle (inclusi quelli standard) facciano la transcodifica secondo le impostazioni di località dell'utente
\end{itemize}
\end{frame}

\subsection{Operazioni sui file}

\begin{frame}[fragile]\frametitle{Test sui file}
\begin{lstlisting}
if (-r $nome_file) { ... };
if (-w $fh) { ... };
\end{lstlisting}

\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!-r! & leggibile \\
\lstinline!-w! & scrivibile \\
\lstinline!-x! & eseguibile \\
\lstinline!-e! & esiste \\
\lstinline!-s! & dimensone (in byte) \\
\lstinline!-f! & è un file \\
\lstinline!-d! & è una directory \\
\lstinline!-M! & età di modifica (giorni) \\
\lstinline!-A! & età di accesso (giorni)
\end{tabular}
\end{frame}

\begin{frame}[fragile]\frametitle{Modificare i file}
\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!rename $src,$dst! & rinomina/sposta un file \\
\lstinline!unlink $file!     & cancella un file
\end{tabular}

\ \\

Ovviamente ci sono altre funzioni, leggete \texttt{perlfunc}.
\end{frame}
%$

\subsection{Moduli da usare} % File::Spec, Path::Class

\begin{frame}[fragile]\frametitle{Manipolazione di path}
\begin{lstlisting}
use strict; use warnings;
use File::Spec;

my ($volume,$dirs,$file)=
 File::Spec->splitpath($path);
my @dirs=File::Spec->splitdir($dirs);
\end{lstlisting}
%$

Non modificate i path ``a mano'': non tutti usano \texttt{/} come separatore.
\end{frame}

\begin{frame}[fragile]\frametitle{Manipolazione di path più semplice}
\lstinline!File::Spec! è scomodo.

\begin{lstlisting}
use strict; use warnings;
use Path::Class;

my $file=file($nome);
my $dir=$file->parent;
my $fh=$file->open('r');
$file->remove();
\end{lstlisting}

\lstinline!Path::Class! rende le cose molto più semplici e leggibili, e ha molti metodi comodi. Installatelo e studiate la documentazione.
\end{frame}

\section{Directory}

\subsection{Le funzioni} % glob, opendir, readdir

\begin{frame}[fragile]\frametitle{Elencare i file}
\begin{lstlisting}
my @nomi_file=glob('/path/alla/dir/*.txt');
\end{lstlisting}

Attenti ai nomi contenenti spazi, \lstinline!glob! non fa sempre quel che volete.
\end{frame}

\begin{frame}[fragile]\frametitle{Elencare i file, più a mano}
\begin{lstlisting}
my $dh;
opendir $dh,'/path/alla/dir';
while (my $nome=readdir $dh) {
  print "/path/alla/dir/$nome\n";
}
closedir $dh;
\end{lstlisting}

\begin{itemize}
\item \lstinline!opendir my $dh,'/path'! non funziona (stranamente) %$
\item notare che \lstinline!readdir! restituisce nomi locali
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Modificare le directory}
\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!mkdir $nome! & crea una directory \\
\lstinline!rmdir $nome! & cancella una directory vuota
\end{tabular}

\ \\

Ovviamente ci sono altre funzioni, leggete \texttt{perlfunc}.
\end{frame}

\subsection{Moduli da usare} % File::Find, File::Find::Rule, File::Next


\begin{frame}[fragile]\frametitle{\texttt{File::Find}}
\begin{lstlisting}
use strict;use warnings;
use File::Find;

find(\&usali,'/path/in/cui/cercare')
sub usali {
 print "$File::Find::name\n";
}
\end{lstlisting}

È un po' scomodo, ma fa tutto quel che vi serve.
\end{frame}
%$

\begin{frame}[fragile]\frametitle{\texttt{File::Next}}
\begin{lstlisting}
use strict;use warnings;
use File::Next;

my $files=
 File::Next::files('/path/in/cui/cercare');
while (defined(my $file = $files->())) {
 print "$file\n";
}
\end{lstlisting}

Molto più comodo. Notare il \lstinline!$files->()!: studiate \texttt{perlref}.
\end{frame}
%$

\begin{frame}[fragile]\frametitle{Manipolazione di path più semplice}
\lstinline!Path::Class! aiuta anche per le directory.

\begin{lstlisting}
use strict; use warnings;
use Path::Class;

my $dir=dir($nome);
$dir->mkpath; # crea l'albero
$dir->rmtree(); # cancella l'albero
while (my $file = $dir->next) { ... }
\end{lstlisting}
\end{frame}

\section{Processi}

\subsection{Le funzioni} % system, exec, qx, fork/wait

\subsection{Moduli da usare} % IPC::Run

\section{Argomenti avanzati}

\begin{frame}\frametitle{Cose non di base}
\begin{itemize}
\item non sono proprio ``avanzate''
\item ma nemmeno troppo basilari
\item servono soprattutto per capire il codice ``idiomatico''
\end{itemize}
\end{frame}

\subsection{Variabili speciali} % $_, @_ e @ARGV

\begin{frame}[fragile]\frametitle{Variabile implicita}
\begin{overprint}
\onslide<1|handout:1>
\begin{lstlisting}
print for @lista;
\end{lstlisting}
\onslide<2|handout:0>
\begin{lstlisting}
for (@lista) {
  print;
}
\end{lstlisting}
\onslide<3|handout:0>
\begin{lstlisting}
for $_ (@lista) {
  print $_;
}
\end{lstlisting}
\onslide<4|handout:0>
\begin{lstlisting}
for my $elem (@lista) {
  print $elem;
}
\end{lstlisting}
\end{overprint}
\end{frame}

\begin{frame}[fragile]\frametitle{Variabile implicita (2)}
\lstinline!$_! è una variabile che viene usata implicitamente da molti costrutti e funzioni.

\begin{lstlisting}
while (<>) {
 chomp;
 next if /^\s*#/;
 my @fields=split;
}
\end{lstlisting}

Leggete \texttt{perlvar} per i dettagli. %$
\end{frame}

\begin{frame}[fragile]\frametitle{Altre variabili speciali}
\rowcolors[]{1}{blue!20}{blue!10}
\begin{tabular}{l|l}
\lstinline!@_! & argomenti della sub \\
\lstinline!@ARGV! & argomenti al programma \\
\lstinline!$1!\ldots & catture dell'ultimo match \\
\lstinline!%ENV! & variabili di ambiente \\
\lstinline!$.! & numero di riga in input \\
\lstinline/$!/ & errore di sistema
\end{tabular}

\ \\

Leggete \texttt{perlvar} per le altre.
\end{frame}
%$

\subsection{Manipolazione di stringhe} % substr, sprintf

\begin{frame}[fragile]\frametitle{\texttt{substr}}
\begin{lstlisting}
my $stringa='abcdefghi';
print substr($a,3,2),"\n";
substr($a,6,3)='GHIJK';
print "$a\n";
\end{lstlisting}

\visible<2->{
\lstinline!de!

\lstinline!abcdefGHIJK!
}
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{printf} e \texttt{sprintf}}
\begin{lstlisting}
printf "%03d - %10s\n",12,'testo';
my $a=sprintf "%03d - %10s\n",12,'testo';
\end{lstlisting}
%$

Come in C.
\end{frame}

\subsection{Manipolazione di liste} % sort, grep, map

\begin{frame}[fragile]\frametitle{\texttt{sort}}
\begin{lstlisting}
my @lista=qw(u y i d f g h c u e a);
my @lista_ordinata=sort @lista;
\end{lstlisting}

\lstinline!sort! restituisce una lista ordinata. Normalmente l'ordinamento è lessicografico tra stringhe.
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{sort} (2)}
\begin{lstlisting}
my @lista=(2,7,6,8,6,5,9);
my @lista_ordinata=sort { $a <=> $b } @lista;
\end{lstlisting}

\lstinline!sort! prende un blocco con la funzione di confronto. \lstinline!<=>! confronta numeri, \lstinline!cmp! confronta stringhe. Il confronto può essere arbitrariamente complesso.
\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{grep}}
\begin{lstlisting}
my @parole_maiuscole=
  grep /^\p{Lu}/ @parole;
my @parolne_lunghe=
  grep { length($_) > 5 } @parole;
\end{lstlisting}
%$

\lstinline!grep! restitusce gli elementi di una lista che soddisfano un certo criterio. Il criterio può essere un'espressione o un blocco. L'elemento da testare si trova in \lstinline!$_! %$

\begin{lstlisting}
# my @out=grep {test($_)} @in;
my @out;
for my $elem (@in) {
 if (test($elem)) {
  push @out,$elem;
 }
}
\end{lstlisting}

\end{frame}

\begin{frame}[fragile]\frametitle{\texttt{map}}
\begin{lstlisting}
my @maiuscole=map {uc($_)} @minuscole;
\end{lstlisting}
%$

\lstinline!map! restituisce la lista dei risultati di un blocco, applicato a ciascun elemento di una lista.

\begin{lstlisting}
# my @out=map {trans($_)} @in;
my @out;
for my $elem (@in) {
 push @out,trans($elem);
}
\end{lstlisting}
\end{frame}
%$

\subsection{Indici multipli} % array & hash slices

\begin{frame}[fragile]\frametitle{Array slice}
\begin{lstlisting}
my @tutti=('a'..'z');
my @alcuni=@tutti[1,3,5,7];
@tutti[1,3,5,7]=('A'..'D');
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Hash slice}
\begin{lstlisting}
my %tutti;
@tutti{'a'..'z'}=0..25;
my @alcuni_val=@tutti{qw(x y z)};
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Hash come insiemi}
\begin{lstlisting}
my %insieme;
@insieme{@elementi}=();
if (exists $insieme{gino}) { ... }
\end{lstlisting}
%$

L'assegnamento di lista vuota imposta tutti i valori a \lstinline!undef!: è il modo che occupa meno memoria.
\end{frame}

\subsection{Operatori logici} % short-circuiting, do or die

\begin{frame}[fragile]\frametitle{Short-circuit}
\begin{lstlisting}
open my $fh,'<',$nome
 or die "Errore: $!";
\end{lstlisting}
%$

\begin{itemize}
\item gli operatori logici (\lstinline!and!, \lstinline!or!, \lstinline!&&!, \lstinline!||!) eseguono solo il minimo necessario
\item \lstinline!and! e \lstinline!&&!:
 \begin{itemize}
 \item valuta la parte sinistra
 \item se il valore è {\em falso} lo restituisce
 \item altrimenti restituisce il valore della parte destra
 \end{itemize}
\item \lstinline!or! e \lstinline!||!:
 \begin{itemize}
 \item valuta la parte sinistra
 \item se il valore è {\em vero} lo restituisce
 \item altrimenti restituisce il valore della parte destra
 \end{itemize}
\end{itemize}
\end{frame}

\end{document}

% - 
% Local Variables:
% mode: outline-minor
% outline-regexp: "\\(. -+ \\)\\|\\\\part\\|\\\\section\\|\\\\subsection"
% coding: iso-8859-1
% tex-command: "pdflatex"
% tex-main-file: "corso.slides.tex"
% End:
