summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordakkar <dakkar@luxion>2008-09-09 12:52:53 +0000
committerdakkar <dakkar@luxion>2008-09-09 12:52:53 +0000
commitb2102c05f88a5d7479575f1259d2a0850c46d832 (patch)
treecdc5acf5483a8a40f71f1e19893d91a3fda54d2a
parenttalk "best practices in perl" per ipw2008 (diff)
downloadbest-practices-b2102c05f88a5d7479575f1259d2a0850c46d832.tar.gz
best-practices-b2102c05f88a5d7479575f1259d2a0850c46d832.tar.bz2
best-practices-b2102c05f88a5d7479575f1259d2a0850c46d832.zip
best practices
git-svn-id: svn://luxion/repos/best-practices@369 fcb26f47-9200-0410-b104-b98ab5b095f3
-rw-r--r--pbp.content.tex293
-rw-r--r--pbp.handout.tex4
-rw-r--r--pbp.slides.tex2
3 files changed, 299 insertions, 0 deletions
diff --git a/pbp.content.tex b/pbp.content.tex
new file mode 100644
index 0000000..e6c9da3
--- /dev/null
+++ b/pbp.content.tex
@@ -0,0 +1,293 @@
+\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}
+{\huge Scrivi sempre codice come se la persona che lo deve mantenere fosse un violento psicopatico che sa dove abiti}
+\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}
+
+\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{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}
+
+\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}
+
+\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}
+
+\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}
+
+\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}
+
+\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}
+
+\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}
+
+\begin{frame}[fragile]\frametitle{I/O}
+\begin{itemize}
+\item \lstinline|open my $fh,'<',$nomefile| \lstinline|or croak qq{Impossibile aprire "$nomefile": $!};| invece che \lstinline|open FH,$nomefile;| %$
+\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}
+
+\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}
+
+\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 \lstinline|my ($nome,$valore) =| \lstinline|($linea=~m{\A (\w+) \s*=\s* (.*?) \z}smx)|, non \lstinline|$linea=~m{^(\w+)\s*=\s*(.*?)$};| \lstinline|my ($nome,$valore)=($1,$2)| %$
+\item studiate \lstinline|Regexp::Common|
+\end{itemize}
+\end{frame}
+
+\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}
+
+\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}
+
+\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}
+
+\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:
diff --git a/pbp.handout.tex b/pbp.handout.tex
new file mode 100644
index 0000000..52de307
--- /dev/null
+++ b/pbp.handout.tex
@@ -0,0 +1,4 @@
+\documentclass[handout,xcolor=table]{beamer}
+\usepackage{pgfpages}
+\pgfpagesuselayout{2 on 1}[a4paper,border shrink=5mm]
+\input{pbp.content.tex}
diff --git a/pbp.slides.tex b/pbp.slides.tex
new file mode 100644
index 0000000..33f800c
--- /dev/null
+++ b/pbp.slides.tex
@@ -0,0 +1,2 @@
+\documentclass[xcolor=table]{beamer}
+\input{pbp.content.tex}