% $Id$

\section{Variables bis}

\subsection{Références}

\begin{frame}[fragile]
\frametitle{Référence: Concept}
C'est une valeur scalaire\ldots

\pause
\vfill
qui fait référence à un scalaire, un tableau ou un hash.

\pause
\vfill
\begin{itemize}
\item elle contient l'adresse mémoire de l'élément pointé
\pause
\item plusieurs références peuvent pointer la même variable
\pause
\item on peut faire des tableaux de références\ldots
\end{itemize}
\pause
\vfill
\textbf{Ce n'est pas un pointeur au sens C du terme}: \verb.$ref++;. ne donnera rien de bien !!!!
\end{frame}

\begin{frame}[fragile]
\frametitle{Créer des références}
\pause
Référence de tableaux:
\pause
\vfill
\begin{verbatim}
my @tableau = (1, 2, 3);
\end{verbatim}
\pause
Récupérer une référence vers:
\begin{verbatim}
my $tabref = \@tableau;
\end{verbatim}
\pause
Créer une référence vers un nouveau tableau:
\begin{verbatim}
my $tabref = [ @tableau ];
\end{verbatim}
\vfill
\vfill
\pause
Référence de hash:
\pause
\vfill
\begin{verbatim}
my %hash = (a => 1);
\end{verbatim}
\pause
Récupérer une référence vers:
\begin{verbatim}
my $hashref = \%hash;
\end{verbatim}
\pause
Créer une référence vers un nouveau tableau:
\begin{verbatim}
my $hashref = { %hash } ;
\end{verbatim}
\end{frame}

\begin{frame}[fragile]
\frametitle{Utiliser les références}
Pour accéder au contenu la variable référencée on utilise \verb+->+.
\vfill
Pour acceder à la variable elle même: \verb+$$+, \verb+@$+ et \verb+%$+ pour
respectivement les scalaires, tableaux et les hash.

\pause
On créer un réference:
\begin{verbatim}
my $tabref = [ 1, 2, 3 ];
my $hashref = { a => 1 };
\end{verbatim}
\pause
On accède au tableau via la référence:
\begin{verbatim}
$tabref->[0];
$hashref->{a};
\end{verbatim}
\pause
Après tout est presque pareil:
\begin{verbatim}
scalar(@$tabref);
keys %$hashref;
\end{verbatim}

\end{frame}

\begin{frame}[fragile]
\frametitle{Pourquoi les références ?}
Perl aplati les listes, remember ?

\pause
\begin{verbatim}
my @tab1 = (1,2); my @tab2 = (3,4);
my @tab = (@tab1, @tab2);
\end{verbatim}
\verb+@tab+ contient 4 éléments...
\pause
\begin{verbatim}
my @tab1 = (1,2); my @tab2 = (3,4);
my @tab = (\@tab1, \@tab2);
\end{verbatim}
\verb+@tab+ contient 2 éléments qui réferencent des tableaux.
\pause

On accède aux valeurs:
\begin{verbatim}
$tab[0]->[0];
\end{verbatim}
\pause
Ou même plus simplement:
\begin{verbatim}
$tab[0][0];
\end{verbatim}
\ldots qui revient à faire un tableau à 2 dimensions.

\end{frame}

\begin{frame}[fragile]
\frametitle{Références: copain de la mémoire}
\begin{small}
\begin{verbatim}
# très gros tableau
my @tab = ();

fonc(@tab);

sub fonc {
    my @tab = @_; # Créer un copie complète
}
\end{verbatim}
\pause
\begin{verbatim}
# très gros tableau
my @tab = ();

fonc(\@tab);

sub fonc {
    my ($tab) = @_; # Ne copie que la référence
}
\end{verbatim}
\end{small}
\end{frame}

\begin{frame}[fragile]
\frametitle{Références: les pièges}
Déférencer un undef:
\begin{verbatim}
perl -we 'my $ref; print @{ $ref }'
Use of uninitialized value $ref in 
array dereference at -e line 1.
\end{verbatim}
\pause
Voici l'astuce:
\begin{verbatim}
perl -we 'my $ref; print @{ $ref || [] }'
\end{verbatim}
\pause
\vfill
\vfill
Attention au type de variable référencée:
\begin{verbatim}
perl -we 'my $ref = {}; print @{ $ref }'
Not an ARRAY reference at -e line 1.
\end{verbatim}
\pause
\vfill
\vfill
Attention au structure complexes:
\begin{verbatim}
$ref->[0][2]{daleks}[0]{episode}
    {$ennemi}{histoire}[0];
\end{verbatim}
\end{frame}

\begin{frame}[fragile]
\frametitle{Références: dernières choses}
On peut connaitre le type de référence avec \verb+ref()+
\begin{verbatim}
perl -we 'my $ref = {}; print ref $ref'
HASH
\end{verbatim}
\vfill
\vfill
\pause
Tout est là:\\
\verb+man perlreref+
\end{frame}

\subsection{les descripteurs de fichier}

\begin{frame}[fragile]
\frametitle{Fichiers: Version simple}
Version moderne:

Ouvrir un fichier en lecture:
\begin{verbatim}
open(my $handle, '<', 'fichier');
\end{verbatim}
\pause
Lire une ligne:
\begin{verbatim}
my $line = <$handle>;
chomp($line); # strip cariage return
\end{verbatim}
\pause
Fermer le fichier:
\begin{verbatim}
close($handle);
\end{verbatim}
\pause
\vfill
Ancienne méthode:
\begin{verbatim}
open(HANDLE, '<', 'fichier');
my $line = <HANDLE>;
chomp($line); # strip cariage return
close(HANDLE);
\end{verbatim}
\end{frame}

\begin{frame}[fragile]
\frametitle{Fichier: version simple (suite)}

Ouvrir:
\begin{verbatim}
open(my $handle, '>', 'fichier');
\end{verbatim}
\pause
Écrire:
\begin{verbatim}
print $handle "Exterminate !\n";
\end{verbatim}
\begin{textbf}Attention à \verb+print+: pas de \verb+,+ après le file handle\end{textbf}

\pause
\vfill
Fermer:
\begin{verbatim}
close($handle);
\end{verbatim}
\pause
Trois file handle par défaut: \verb+STDIN+, \verb+STDOUT+, \verb+STDERR+
(entrée, sortie, sortie d'erreur).
\end{frame}

\begin{frame}[fragile]
\frametitle{Fichiers: Version compliquée}
Pour des besoins très spécifiques:
\begin{itemize}
\item open()/close()
\item read()/print()
\end{itemize}

\vfill
ou:
\vfill
\pause
\begin{itemize}
\item sysopen()/sysclose()
\item sysread()/syswrite()
\end{itemize}
\pause
\vfill
\vfill
Si vraiment vous voulez en savoir plus: \verb+man+
\begin{itemize}
\item perlfunc
\pause
\item perlopentut
\end{itemize}
\end{frame}

