\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}
}
\mode<article>{\usepackage{fullpage}}
\mode<handout>{\setbeamercolor{background canvas}{bg=black!5}}
%% \AtBeginSection[]{
%% \begin{frame}<beamer>{Argomenti}
%% \small
%% \tableofcontents[sectionstyle=show/shaded,subsectionstyle=show/hide/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}
\begin{itemize}
\item \lstinline!2+3!
\item \lstinline!5-7.5!
\item \lstinline!4*12e3!
\item \lstinline!7/3!
\item \lstinline!5%2!
\item \lstinline!3**7!
\end{itemize}
\end{frame}
\begin{frame}[fragile]\frametitle{Confronto tra numeri}
\begin{itemize}
\item \lstinline!2 < 3!
\item \lstinline!7.5 > 5!
\item \lstinline/4 != 12e3/
\item \lstinline!3 <= 7!
\item \lstinline!5 >= 2!
\item \lstinline!3 == 3!
\end{itemize}
\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}
\begin{itemize}
\item \lstinline!'gino' . 'pino'!
\item \lstinline!'nano' x 7!
\end{itemize}
\end{frame}
\begin{frame}[fragile]\frametitle{Confronto tra stringhe}
\begin{itemize}
\item \lstinline!'gino' lt 'pino'!
\item \lstinline!'nano' gt 'mano'!
\item \lstinline!'str1' ne 'str2'!
\item \lstinline!'abcd' le 'wxyz'!
\item \lstinline!'piri' ge 'piri'!
\item \lstinline!'buh' eq 'buh'!
\end{itemize}
\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}
\begin{itemize}
\item \lstinline!$a{vero}! � vero
\item \lstinline!$a{falso}! � falso
\item \lstinline!$a{non_definito}! � falso
\item \lstinline!exists $a{non_definito}! � vero
\item \lstinline!defined $a{falso}! � vero
\item \lstinline!exists $a{non_ce}! � falso
\end{itemize}
\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
marning)
\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 \lstinline!/s! fa in modo che \lstinline!.! corrisponda anche al
carattere di ``a capo''
\item \lstinline!/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 \lstinline!/x! ignora gli spazi nella regex, per aumentare la
leggibilit� (mettete una \lstinline!\! davanti agli spazi che devono
esserci)
\item \lstinline!/i! fa in modo che maiuscole e minuscole non vengano distinte
\item \lstinline!/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}\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}.
\end{frame}
\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}
\subsection{Leggere e scrivere file}
\subsection{Codifiche} % binmode e use utf8 e use encoding
\subsection{Test sui file}
\subsection{Moduli da usare} % File::Spec, Path::Class
\section{Directory}
\subsection{Le funzioni} % opendir, readdir
\subsection{Moduli da usare} % File::Find, File::Find::Rule, File::Find::Next
\section{Processi}
\subsection{Le funzioni} % system, exec, qx, fork/wait
\subsection{Moduli da usare} % IPC::Run
\section{Argomenti avanzati}
\subsection{Variabile implicita} % $_, @_ e @ARGV
\subsection{Manipolazione di stringhe} % substr, sprintf
\subsection{Manipolazione di liste} % reverse, sort, grep, map
\subsection{Indici multipli} % array & hash slices
\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: