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

\colorlet{p}{black!20}

\lstset{extendedchars,numbers=left,numberstyle=\tiny ,numbersep=5pt,language=Perl,showspaces=false,frame=single,framerule=0pt,backgroundcolor=\color{p},basicstyle=\small\ttfamily ,upquote=true,keepspaces=true}

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

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

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

\begin{document}

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

\begin{frame}\frametitle{Grazie a Damian Conway}
Questo intervento è ispirato a ``Perl Best Practices'', di Damian Conway, edizioni O'Reilly
\end{frame}

\begin{frame}\frametitle{Obiettivi}
\begin{itemize}
\item Robustezza
\item Efficienza
\item Manutenibilità
\end{itemize}
\end{frame}

\begin{frame}\frametitle{Per gli impazienti}
\begin{center}
{\huge Scrivi sempre codice come se la persona che lo deve mantenere fosse un violento psicopatico che sa dove abiti}
\end{center}
\end{frame}

\section{Spaziatura}

\begin{frame}[fragile]\frametitle{Spaziatura}
\begin{lstlisting}
my@result=(1,2,3);
for my$result(@results){print_sep;print($result)}
while(my_func $param,$param2){
my$stuff=$x->{$keys[($x-$y)/2]};
if($stuff<$target){$x=$y}else{$y=$x}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Spaziatura}
\begin{lstlisting}
my @result = ( 
  1,
  2,
  3,
);

for my $result (@results) {
  print_sep();
  print $result;
}

while (my_func($param,$param2)) {
  my $stuff = $x->{ $keys[ ($x-$y)/2 ] };
  if ($stuff < $target) {
    $x = $y;
  }
  else {
    $y = $x;
  }
}
\end{lstlisting}
\end{frame}

\section{Nomi}

\begin{frame}[fragile]\frametitle{Nomi}
\begin{itemize}
\item date nomi comprensibili e non ambigui (\lstinline|$totale_finora|, \lstinline|$utente_attuale|, \lstinline|&è_valido|)
\item non abbiate paura dei nomi lunghi
\item separate con \lstinline|_| e non CamelCase
\item hash al genitivo singolare, array al nominativo plurale
\item non abbreviate troppo
\item cominciate i ``nomi privati'' con \lstinline|_|
\end{itemize}
\end{frame}

\section{Valori}

\begin{frame}[fragile]\frametitle{Valori}
\begin{itemize}
\item usate \lstinline|'virgolette semplici'| tranne quando \lstinline|"dovete $interpolare\n"| %$
\item non abbiate paura di \lstinline|q()| e \lstinline|qq()|
\item in particolare, \lstinline|q[]|, \lstinline|q[ ]|, \lstinline|q[,]|, \lstinline|qq[\t]|
\item usate ``here-doc'' per blocchi di testo
\end{itemize}
\end{frame}

\section{Variabili}

\begin{frame}[fragile]\frametitle{Variabili}
\begin{itemize}
\item dichiarate sempre le variabili con \lstinline|my|
\item non usate \lstinline|local| se non sapete \emph{esattamente} perché
\item non toccate le variabili globali speciali (in particolare \lstinline|@ARGV|)
\item \lstinline|use English '-no_match_vars'|
\item \emph{usate} \lstinline|local| su \lstinline|$_| e altre variabili ``punteggiatura'' %$
\item \lstinline|$array[-1]|, non \lstinline|$array[$#array]| %$
\end{itemize}
\end{frame}

\section{Flusso}

\begin{frame}[fragile]\frametitle{Controlli di flusso}
\begin{itemize}
\item usate \lstinline|if| posposto solo per semplici istruzioni, tipicamente controlli nei cicli: \lstinline|next CICLO if !mi_serve($elemento);| %$
\item usate ancora meno gli altri controlli posposti (\lstinline|unless|, \lstinline|while|, \lstinline|for|)
\item evitate il \lstinline|for(init;cond;step)| alla C
\item date sempre un nome alla variabile di iterazione: \lstinline|for my $persona_attuale (@persone) { ... }| %$
\item usate \lstinline|map| per trasformare le liste (ma non in-place!)
\item usate \lstinline|grep| e \lstinline|List::Util::first| per estrarre elementi
\item usate \emph{dispatch tables} invece che cascate di \lstinline|if|
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{Dispatch tables}
\begin{lstlisting}
{
my %comandi=(
  start  => \&avvia_processo_di_calcolo,
  stop   => \&termina_processo_di_calcolo,
  status => \&esamina_stato_processo,
);

sub esegui_comando {
  my ($comando)=@_;
  if (exists $comandi{$comando}) {
    $comandi{$comando}->();
  }
  else {
    carp qq{Comando "$comando" ignoto.\n};
  }
}
}
\end{lstlisting}
\end{frame}

\begin{frame}[fragile]\frametitle{Controlli di flusso (2)}
\begin{itemize}
\item usate i comandi di controllo cicli (\lstinline|next|, \lstinline|last|, \lstinline|continue|, \lstinline|redo|)
\item etichettate sempre i cicli in cui usate quei comandi:
  \begin{lstlisting}
CLIENTE:
while (my $cliente_corrente = 
          $clienti->next()) {
  next CLIENTE
    if ! $cliente_corrente->attivo;
  usa_cliente($cliente_corrente);
}
\end{lstlisting}
\end{itemize}
\end{frame}

\section{Documentazione}

\begin{frame}[fragile]\frametitle{Documentazione e commenti}
\begin{itemize}
\item usate POD per la documentazione utente
\item usate i commenti per la documentazione interna
\item spiegate gli algoritmi
\item annotate i trucchi e le finezze
\item ``incremento il contatore'' non è documentazione
\end{itemize}
\end{frame}

\section{Built-in}

\begin{frame}[fragile]\frametitle{Funzioni predefinite}
\begin{itemize}
\item studiate la ``Orcish manoeuvre'' e la ``Schwartzian transform''
\item \lstinline|reverse| è molto utile (\lstinline|for my $countdown (reverse 0..100) { ... }|) %$
\item spacchettare dati: \begin{itemize}
      \item \lstinline|unpack| se lunghezza fissa
      \item \lstinline|split| se lunghezza variabile
      \item \lstinline|Text::CSV_XS| se più complicati
      \end{itemize}
\item è quasi sempre possibile evitare \lstinline|eval 'stringa'|
\item usate \lstinline|glob('*')|, non \lstinline|<*>|
\item studiate e usate \lstinline|Scalar::Util|, \lstinline|List::Util|, \lstinline|List::MoreUtils|
\end{itemize}
\end{frame}

\section{Subroutine}

\begin{frame}[fragile]\frametitle{Subroutine}
\begin{itemize}
\item \lstinline|fai_qualcosa(@argomenti)|, non \lstinline|&fai_qualcosa @argomenti|
\item per prima cosa, spacchettate \lstinline|@_|
\item se la sub prende più di un paio di argomenti, passateli per hash
\item attenti al contesto nei vostri \lstinline|return|
\item \lstinline|return;| garantisce che il risultato sia falso, anche in contesto lista
\item mettete sempre un qualche \lstinline|return| alla fine delle sub
\end{itemize}
\end{frame}

\section{I/O}

\begin{frame}[fragile]\frametitle{I/O}
\begin{itemize}
\item \begin{lstlisting}
open my $fh,'<',$nomefile
or croak qq{Impossibile aprire "$nomefile": $!};
\end{lstlisting}
invece che \begin{lstlisting}
open FH,$nomefile;
\end{lstlisting} %$
\item<2> filehandle lessicali
\item<2> \lstinline|open| a 3 argomenti
\item<2> controllate sempre il valore di ritorno
\end{itemize}
\end{frame}

\begin{frame}[fragile]\frametitle{I/O (2)}
\begin{itemize}
\item \lstinline|while (my $line=<$fh>)|, non \lstinline|for|
\item evitate il più possibile di caricare l'intero file in memoria
\item se proprio dovete, usate \lstinline|File::Slurp|
\item \lstinline|print {$logfile} $messaggio|, non \lstinline|print $logfile $messaggio|
\item studiate \lstinline|IO::Handle| e famiglia
\end{itemize}
\end{frame}

\section{References}

\begin{frame}[fragile]\frametitle{References}
\begin{itemize}
\item non usate \emph{mai} reference simboliche (\lstinline|"${nome}_tipo"=5|) %$
\item \lstinline|$list_ref->[$indice]|, non \lstinline|$$list_ref[$indice]| %$
\item \lstinline|@{$hoa{$chiave}}|, non \lstinline|@$hoa{$chiave}|
\end{itemize}
\end{frame}

\section{Regex}

\begin{frame}[fragile]\frametitle{Espressioni regolari}
\begin{itemize}
\item usate sempre \lstinline|/xms|
\item \lstinline|\A| e \lstinline|\z| per inizio e fine \emph{stringa}
\item \lstinline|^| e \lstinline|$| per inizio e fine \emph{riga} %$
\item \lstinline|m{...}smx|, non \lstinline|/.../|
\item \lstinline|\p{Uppercase}\p{Alphabetic}|, non \lstinline|[A-Z][a-zA-Z]|
\item attenti alla differenza tra \lstinline|.*| e \lstinline|.*?|
\item \begin{lstlisting}
my ($nome,$valore) =
 ($linea=~m{\A (\w+) \s*=\s* (.*?) \z}smx)
\end{lstlisting}
invece che \begin{lstlisting}
$linea=~m{^(\w+)\s*=\s*(.*?)$};
my ($nome,$valore)=($1,$2)
\end{lstlisting} %$
\item studiate \lstinline|Regexp::Common|
\end{itemize}
\end{frame}

\section{Eccezioni}

\begin{frame}[fragile]\frametitle{Eccezioni}
\begin{itemize}
\item lanciate eccezioni, non impostate flag o valori di ritorno
\item studiate \lstinline|autodie|
\item studiate \lstinline|Exception::Class| o simili
\item usate \lstinline|Carp|
\end{itemize}
\end{frame}

\section{OOP}

\begin{frame}[fragile]\frametitle{Oggetti}
\begin{itemize}
\item usate \lstinline|Moose|
\item non usate oggetti dove non servono
\item usateli \emph{sempre} dove servono
\item \lstinline|$oggetto->metodo(@args)|, non \lstinline|metodo $oggetto @args|
\item evitate \lstinline|AUTOLOAD|
\end{itemize}
\end{frame}

\section{Moduli}

\begin{frame}[fragile]\frametitle{Moduli}
\begin{itemize}
\item non ripetete mai il codice: fattorizzate \emph{sempre}
\item nascondete le implementazioni dentro moduli
\item attenti ai nomi che esportate
\item evitate di esporre variabili o altro stato globale
\item non scrivete moduli: usate quelli in CPAN
\end{itemize}
\end{frame}

\section{Varie}

\begin{frame}[fragile]\frametitle{Varie}
\begin{itemize}
\item scrivete test, e usateli
\item usate un debugger
\item usate un sistema di controllo delle versioni
\item non fate ottimizzazioni alla cieca -- misurate i tempi (\lstinline|Benchmark|, \lstinline|Devel::NYTProf|)
\item non fate ottimizzazioni alla cieca -- misurate l'occupazione di memoria (\lstinline|Devel::Size|)
\end{itemize}
\end{frame}

\end{document}

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