\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,printpod=true,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}
\subsection{Cosa sono}
\subsection{Casi semplici} % literal, simple charclass, repetition
\subsection{Operatori pi� complessi} % anchors, parens, complex charclass (\p)
\subsection{Uso generale} % m, s, split, =~, options, tr
\section{Controllo del flusso}
\subsection{Controlli negati} % unless, until
\subsection{Modificatori}
\subsection{\texttt{for}}
\subsection{Controllo dei cicli}
\section{Moduli}
\subsection{Cosa sono}
\subsection{CPAN}
\subsection{Installazione} % CPAN.pm, distribuzioni e local::lib
\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} % $_
\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: