From 65180664920e019e675221729be54fcc0d9b3d1b Mon Sep 17 00:00:00 2001 From: dakkar Date: Mon, 18 Aug 2008 13:03:34 +0000 Subject: file e directory git-svn-id: svn://luxion/repos/intro-perl@360 fcb26f47-9200-0410-b104-b98ab5b095f3 --- corso.content.tex | 347 +++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 302 insertions(+), 45 deletions(-) diff --git a/corso.content.tex b/corso.content.tex index 8124cad..d5a6839 100644 --- a/corso.content.tex +++ b/corso.content.tex @@ -234,25 +234,27 @@ use warnings; \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} +\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} -\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} +\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} @@ -288,21 +290,23 @@ Stringhe racchiuse tra virgolette doppie: \end{frame} \begin{frame}[fragile]\frametitle{Operazioni sulle stringhe} -\begin{itemize} -\item \lstinline!'gino' . 'pino'! -\item \lstinline!'nano' x 7! -\end{itemize} +\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} -\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} +\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} @@ -954,14 +958,15 @@ my %a=( vero => 1, 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} +\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}} @@ -1161,7 +1166,7 @@ print "$righe\n"; leggendone una alla volta \item \lstinline!$righe! vale \lstinline!undef! all'inizio, ma %$ l'operatore di incremento lo trasforma in \lstinline!0! (senza -marning) +warning) \item \lstinline!reverse! inverte anche le stringhe \end{itemize} \end{frame} @@ -1434,17 +1439,17 @@ s/ \end{lstlisting} \begin{itemize} -\item \lstinline!/s! fa in modo che \lstinline!.! corrisponda anche al +\item \verb!/s! fa in modo che \lstinline!.! corrisponda anche al carattere di ``a capo'' -\item \lstinline!/m! fa in modo che \lstinline!^! e \lstinline!$! +\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 \lstinline!/x! ignora gli spazi nella regex, per aumentare la +\item \verb!/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 +\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} @@ -1640,8 +1645,12 @@ Questo scarica, testa, e installa il modulo che avete chiesto. Notare che alcuni 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 @@ -1656,19 +1665,265 @@ Il modulo \texttt{local::lib} semplifica il procedimento per installare moduli n \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 -\subsection{Test sui file} +\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} % opendir, readdir +\subsection{Le funzioni} % glob, opendir, readdir -\subsection{Moduli da usare} % File::Find, File::Find::Rule, File::Find::Next +\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} @@ -1686,6 +1941,8 @@ Il modulo \texttt{local::lib} semplifica il procedimento per installare moduli n \subsection{Indici multipli} % array & hash slices +\subsection{Operatori logici} % short-circuiting, do or die + \end{document} % - -- cgit v1.2.3