Programmer en Perl
Transcription
Programmer en Perl
. p. 1 p. 2 Plan Programmer en Perl François Gannaz – SILECS Formation Continue Grenoble INP . . Historique Présentation L’esprit de Perl Installation et environnement de développement Premier contact avec Perl 1 Introduction à Perl 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées 5 Modules 6 Interactions et communication 7 Incomplétude p. 3 p. 4 Au commencement… Perl, c’est-à-dire… Le nom de Perl a pour origine : Une citation des évangiles, ”A pearl of great price”, Matthew, 13 :46. Larry Wall, le fondateur diplômé de linguistique programmeur émérite en C créateur de patch Trois vertus du programmeur : Laziness, Impatience and Hubris Pratical Extraction and Report Language Langage pratique d’extraction et de génération de rapports. Pathologically Eclectic Rubbish Lister Listeur pathologique de débris éclectiques. Perl 1 en 1987, Perl 4 stable en 91 Sous licence artistique (et GPL) Perl 5 en 1994 Récriture complète du langage Perl. Le futur : Perl 6, débuté en 2002 Nouveau langage, différent de Perl 5. Implémenté par Rakudo star sur la machine virtuelle Parrot. . . . p. 5 p. 6 Les caractéristiques de Perl Domaine de compétence Perl est un langage interprété. Un programme perl n’est pas compilé pour produire un exécutable indépendant. Perl n’est pas recommandé pour : Exécutables autonomes Spécialités Perl : Le traitement du texte En particulier, les expressions régulières. Structures évoluées Langage de haut niveau : des types de données complexes sont intégrés au langage Souplesse There is more than one way to do it. . Performance cruciale en temps ou en mémoire Programmation bas niveau (drivers, noyau) Perl est adapté et utilisé pour : Manipulation de texte Web Administration système Domaines spécialisés (bioinformatique, etc.) Du point de vue du développeur, la tâche est simplifiée : Syntaxe proche du C, de sed et de sh Faiblement typé (conversions transparentes) . p. 7 p. 8 Documentation La licence artistique La documentation officielle de Perl est excellente et regorge d’exemples. Perl à la réputation de produire du code sale : faiblement typé Doc générale Table des matières : perldoc perl Par ex., fonctions par catégories : man perlfunc There is more than one way to do it. On peut imposer une dose de rigueur à Perl, mais ce ne sera jamais du Java. Rechercher une fonction perldoc -f fonction Les langues sont fondamentalement amorales. La langue n’est pas le niveau auquel on devrait obliger à ”penser bien”. On ne peut garantir la moralité par la syntaxe. Rechercher dans la FAQ perldoc -q motif En ligne Larry Wall perl.org Le site officiel du langage. cpan.org Le dépôt central des modules Perl. . . . p. 9 p. 10 Installation sous Linux Installation sous Mac OS X Perl est déjà installé ! Perl est déjà installé ! Éditeurs Éditeurs Vim et Emacs (cperl-mode) sont excellents. Les éditeurs du monde Unix : Vim et Emacs (Carbon Emacs) Beaucoup d’éditeurs libres légers : de Gedit (généraliste) à Geany (orienté code). IDE multi plates-formes : Beaucoup d’éditeurs payants : TextMate, BBedit, Affrus. . . IDE multi plates-formes : Eclipse + EPIC : attention, très lourd Pour tous langages, dont Perl. http://www.epic-ide.org/ Komodo Edit Pour Perl, Python, Ruby, PHP. http://www.activestate.com/komodo-edit/ Padre : uniquement pour du code Perl En cours de développement Debian : aptitude install padre/unstable Eclipse + EPIC : attention, très lourd Pour tous langages, dont Perl. http://www.epic-ide.org/ Komodo Edit Pour Perl, Python, Ruby, PHP. http://www.activestate.com/komodo-edit/ . . p. 11 p. 12 Installation sous Windows Le premier programme Perl n’est pas installé ! Deux distributions possibles : ActivePerl, http://www.activestate.com/activeperl support commercial, meilleure intégration à Windows. Strawberry Perl, http://strawberryperl.com/ distribution plus ouverte, proche de UNIX. print "Hello, world !\n" ; hello.pl Éditeurs Exécution : Les classiques sous Windows comme Notepad++ (libre). Les portages venant d’Unix : gvim et Emacs. IDE multi plates-formes : . Eclipse + EPIC : attention, très lourd http://www.epic-ide.org/ Komodo Edit http://www.activestate.com/komodo-edit/ Padre : uniquement pour du code Perl Utiliser de préférence le paquet StrawberryPerl+Padre http://padre.perlide.org/download.html foo@bar> perl hello.pl . . p. 13 p. 14 Le premier programme Premiers exemples Intégration dans unix # !/usr/bin/perl print("Hello, world !\n"); One-liner % perl -i.BAK -C -pe 's#<(/?\p{Ll}+)>#<\L$1>#' *.xml hello2.pl Exécution : Met en minuscule toutes les balises des fichiers XML en créant une copie de sauvegarde en .xml.BAK. foo@bar> chmod u+x hello2.pl foo@bar> ./hello2.pl Intégration dans Windows Associer l’extension .pl avec l’interpréteur Perl (perl.exe). . . p. 15 p. 16 Premiers exemples Exemple d’utilisation de Perl Script Situation # !/usr/bin/perl -w foreach (glob "*") { s/\d/*/g ; s/\.[^\.]+?$// ; $motif{$_}++ ; } foreach (sort keys %motif) { print "'$_' $motif{$_} occurrences.\n" ; } Répertoire contenant 999 fichiers : file1.html …file50.html …file999.html Objectif Les renommer en : file001.html …file050.html …file999.html Solution Utiliser la commande unix rename. rename 's/^file(\d)\./file0$1./' rename 's/^file(\d\d)\./file0$1./' Regroupe les fichiers selon leur nom privé de chiffres, et affiche le nombre d’occurrences. . . . p. 17 p. 18 # !/usr/bin/perl -w # rename - Larry's filename fixer $op = shift or die "Usage: rename expr [files]\n" ; chomp(@ARGV = <STDIN>) unless @ARGV ; for (@ARGV) { $was = $_ ; eval $op ; die $@ if $@ ; rename($was,$_) unless $was eq $_ ; } Le programme rename # !/usr/bin/perl -w # rename - Larry's filename fixer $op = shift or die "Usage: rename expr [files]\n" ; chomp(@ARGV = <STDIN>) unless @ARGV ; for (@ARGV) { $was = $_ ; eval $op ; die $@ if $@ ; rename($was,$_) unless $was eq $_ ; } Commentaires # : commentaires {...} : bloc C’est un script Perl ! ; : fin de commande indentation non signifiante . . p. 19 p. 20 Plan 1 . Variables Déclaration Introduction à Perl Données Structures de contrôle Fonctions Commandes internes essentielles Entrées/sorties 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées 5 Modules 6 Interactions et communication 7 Incomplétude La déclaration n’est pas obligatoire. # !/usr/bin/perl $variable = 13; La variable est créée à la première utilisation. Par défaut, elle vaut toujours undef. Programmation propre La directive use warnings teste la cohérence du code. Et use strict impose une déclaration préalable avec my. # !/usr/bin/perl -w use strict ; use warnings ; my $variable ; $variable = 14 ; . . p. 21 p. 22 Types de données Scalaires Perl est faiblement typé. Ce sont toutes les données simples (non-composées) de Perl. Perl connaît 3 types de données : scalaires Données non-composées : nombres, chaînes de caractères,… 1 -10.02 Une variable scalaire s’écrit $a, $var,… $n = 14; $texte = "Perl" ; "texte" tableaux Tableaux unidimensionnels de scalaires $hex=0xff ; my $txt='Perl 5' ; Les scalaires peuvent se ranger en 3 catégories : nombre (1, "deux", 3, "quatre") texte tableaux associatifs (tables de hachage, hashes) À un scalaire donné, on associe un scalaire. référence Perl se charge des conversions, elles ne sont pas explicites. ( "un" => 1 , "deux" => 2, -1 => 1 ) . . p. 23 p. 24 Les scalaires : les nombres Les scalaires : les chaînes de caractères Interpolation Opérateurs numériques Sans interpolation $t='Salut !' ; Salut ! $t='Salut\n a \\toi' ; Salut\n␣a␣\toi $t='j\'arrive' ; j'arrive Tous les caractères sont conservés, sauf \\ et \́. Identiques à ceux du C. Affectation : = Calcul : + - * / Combiné : += -= *= /= Modulo : % Comparaison : == < <= > >= != Incrémentation/décrémentation : ++ - - Avec interpolation $t="Salut\n a \\toi" ; Opérateurs supplémentaires. Exponentiation : ** Comparaison : <=> . . Salut ␣a␣\toi $a='Perl' ; $b="Le chameau de $a" ; Le␣chameau␣de␣Perl $j=40; $t="Les $j voleurs" ; Les␣40␣voleurs . p. 25 p. 26 Les scalaires : les chaînes de caractères Exercices . Proposer au moins 2 méthodes différentes d’afficher la concaténation de 2 chaînes $a1 et $a2. . Écrire le programme ”Hello world !” en Perl en utilisant une variable pour chaque mot. 3. Que se passe-t-il quand on incrémente une variable 1 Opérateurs Concaténation : . Réplication : x Comparaison : eq lt 2 le gt ge ne inexistante ? Quand on l’affiche ? Expérimenter. . Qu’affichent les instructions suivantes ? $a = 1 ; $b = "2+$a" ; $a = 2 ; print $b ; 5. Les expressions suivantes sont-elles vraies ou fausses ? Mots-clés : equal, less than, less or equal, greater than,… 4 La comparaison se fait selon l’ordre lexicographique. Exemples $chant = 'tra' . "la"x3 ; # $chant=”tralalala” ; if ("la" le $chant) { print "OK !\n" ; # Affiche : OK ! } (1 < "un") (1 lt "un") .6 Que donne print((2+3)x4); ? . . p. 27 p. 28 Les tableaux Les tableaux : opérations fondamentales Qu’est-ce ? C’est une variable contenant une liste de scalaires. Un nom de tableau débute toujours par @. Concaténation de listes @a = (1, 2); @b = (@a, 3); @b = (@b, 4); Écriture littérale de listes Entre parenthèses, scalaires séparés par des virgules. @a @b my my = (1, 2, 3); = (1, "deux", 3); @tab = ($a, $une_autre_variable); @tableau_vide = (); On utilise souvent push pour l’empilement en fin de tableau. Taille d’un tableau @a = ( 0 .. 10 ); $derIndice = $#a ; $taille = @a ; Astuces Opérateur qw : quote word qw(Aleph Uqbar Zahir) équivaut à ("Aleph","Uqbar","Zahir"). . Opérateur .. : (1 .. 5) équivaut à (1,2,3,4,5). # @b=(1,2,3) # @b=(1,2,3,4) . # $derIndice=10; # $taille=11; . p. 29 p. 30 Accès aux éléments d’un tableau Exercices Chaque élément est un scalaire, donc pour un tableau @tab, on écrit le premier élément $tab[0]. . Expérimenter l’interpolation de tableaux, c’est-à-dire "@tab", "$tab[0]". Quelle est la différence entre print @a et print "@a" ? .2 Qu’affiche le programme suivant ? 1 my @b = (1, 2, 3, 4); # lire la premiere case du tableau $un = $b[0]; # $un=1; @a = (1,9,3,7,5); @b = (3,2,1); $b[1] = @a ; print "@b\n" ; # lire les 2 premieres cases a la fois ($un,$deux) = @b ; # $un=1; $deux=2; . Les arguments d’un programme sont dans un tableau @ARGV. Écrire un programme qui affiche le dernier et le premier de ses arguments. 4. Échanger deux variables scalaires sans utiliser de variable 3 # modifier la case de rang 2 (la troisieme) $b[2] = 8 ; # @b=(1,2,8,4); # choisir l'element en comptant depuis la fin $quatre = $b[-1]; # $quatre=4; intermédiaire. . . p. 31 p. 32 Contexte Exercices (suite) Que donne $scalaire=@tableau; ? Perl doit évaluer une liste dans un contexte scalaire. Il effectue alors une conversion implicite. On peut forcer le contexte avec scalar(...). . Écrire un programme qui affiche l’argument dont le rang est donné par le dernier argument. Par exemple, ./test.pl 0 1 2 trois quatre 3 devra afficher trois. 6. En utilisant la syntaxe while ($in=<STDIN>) {…}, saisir des 5 Principe valeurs ligne par ligne jusqu’à apparition d’une ligne vide. Demander alors le numéro de la ligne à afficher parmi celles saisies. Une ”fonction” peut renvoyer des valeurs distinctes suivant le contexte. $a = <$filehandle> ; # lire une ligne du fichier @a = <$filehandle> ; # lire toutes les lignes du fichier . Comment extraire un sous-tableau ? Expérimenter. Comment insérer un élément dans un tableau ? 7 Et réciproquement ? @tableau=$scalaire; Et réciproquement ? @tableau=($scalaire); . . . p. 33 p. 34 Les tableaux associatifs Hashes : opérations fondamentales Accéder à un élément Qu’est-ce qu’un hash ? $hash{"maclé"} renvoie la valeur scalaire associée à "maclé". C’est une collection de clés scalaires telle qu’à chaque clé est associée une valeur scalaire. Un nom de hash débute toujours par %. %notes = ("Hyppolyte"=>12, "Achille"=>7, "Baudoin"=>9); $eleve = 'Baudoin' ; print "La note de $eleve : $notes{$eleve}.\n" ; Écriture d’un hash On peut le définir de façon globale. Tester un élément : exists %h1 = ("un"=>1 , "deux"=>2); %h2 = ( "Grenoble" => 38000, "Lyon" => 69000 ); Pour tester l’existence d’une variable scalaire, on utilise if ($a) ou mieux if (defined $a). Pour tester l’existence d’une clé dans un hash, il faut utiliser if (exists $h{"maclé"}). Ou le définir séparément pour chaque paire clé/valeur. my %h ; $h{"un"}=1 ; $h{deux}=2 ; Effacer un élément : delete %notes = ("Hyppolyte"=>12, "Achille"=>7, "Baudoin"=>9); delete $notes{Achille} ; . . p. 35 p. 36 Hashes : opérations fondamentales (2) Exercices . Écrire un programme qui convertisse un chiffre donné en toutes lettres en argument en valeur numérique. Exemple : ./chiffre.pl trois affichera ”3”. 2. En utilisant while ($in=<STDIN>) {…}, écrire un 1 keys renvoie la liste des clés d’un hash. %h = ( "premier" => 1 , "second" => 2 ); @indices = keys(%h); # @indices=qw(premier second); foreach $index (@indices) { print "$index => $h{$index}\n" ; } programme qui saisisse les noms et les notes d’élèves. . Qu’affiche le programme suivant ? # !/usr/bin/perl @keys = sort keys %ENV ; foreach $key (@keys) { print "$key = $ENV{$key}\n" ; } 4. En utilisant la syntaxe while ($mot=<STDIN>) {…}, saisir un mot par ligne, et dire si ce mot a déjà été saisi. Modifier ensuite le programme pour afficher après chaque saisie le nombre d’apparitions de chaque mot. 3 values renvoie la liste des valeurs d’un hash. %h = ( "premier" => 1 , "second" => 2 ); @val = values(%h); # @val=(1,2); . . . p. 37 p. 38 Plan 1 Structures conditionnelles : if/unless Introduction à Perl Données Structures de contrôle Fonctions Commandes internes essentielles Entrées/sorties Booléens Les valeurs fausses sont 0, "", () et undef. Syntaxe courante if (condition) { faire ; faire ; …} if ($ARGV[0] eq "--verbose") { print "Verbeux.\n" ; } elsif (-f $ARGV[-1]) { print "Le fichier $ARGV[-1] existe.\n" ; } 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées 5 Modules faire if (condition) ; 6 Interactions et communication print "Verbeux.\n" if ($ARGV[0] eq "--verbose"); print "Stop!" unless $OK ; 7 Incomplétude Syntaxe familière . . p. 39 p. 40 Boucles : while/until Boucles : foreach Syntaxe : foreach $variable (@tableau) { ... } Parcourt tous les éléments d’un tableau. @tab = (1,3,5,7,9,"..."); foreach $k (@tab) { print "$k -> " ; } Affichera 1 -> 3 -> 5 -> 7 -> 9 -> ... -> Syntaxe courante while (condition) { faire ; faire ; …} until ($a>2) { print ++$a ; } while ($a) { print $a-- ; } Remarques Affichera ? ”123321”. Le scalaire utilisé par foreach est local à ce bloc. Ce scalaire est un alias sur l’élément du tableau (modifiable). Syntaxe familière faire while (condition) ; print ++$a until $a>2 ; print $a-- while $a ; . . @a = (1..5); foreach $i (@a) { $i *= 3 ; } print "@a" ; Affichera ”3 6 9 12 15”. . p. 41 p. 42 Variables implicites Exercices Perl utilise des variables par défaut, généralement $_ et @_, quand aucune variable n’est précisée. foreach my $i (@tableau) { print $i ; } . Écrire un programme qui affiche ses arguments, un par ligne. . En utilisant $in=<STDIN> pour saisir les valeurs, programmer 1 2 Peut être abrégé en : foreach (@tableau) { print ; } le jeu de devinette d’un entier fixé entre 1 et 99. . Afficher la somme des arguments du programme en écrivant l’opération. Par exemple, ./somme.pl 1 2 3 4 affichera 1+2+3+4=10. 4. Écrire un programme qui affiche ses arguments accompagnés ou même : 3 print foreach (@tableau); de leur nombre de caractères (utiliser la documentation). Quelques fonctions n’utilisent pas $_ par défaut. Par exemple, shift s’applique toujours aux arguments : @ARGV dans le corps du programme, @_ dans une une fonction. . . p. 43 p. 44 Compléments Compléments (2) Opérateurs or et and last Ce sont les mêmes opérateurs que || et && mais avec une priorité minimale. Quitte la boucle en cours. foreach $arg (@ARGV) { last if ($arg eq "--quit"); print "$arg\n" ; } $arg = shift or die "Le programme a besoin d'un argument" ; Perl n’évalue que la partie gauche d’une expression si cela suffit à en donner la valeur. next . Affectation par défaut Passe à l’itération suivante de la boucle en cours. Une syntaxe fréquente : ||= et //= foreach $k (@tab) { next unless $hash{$k} ; $k += $hash{$k} ; } use strict ; my ($x, $y); $x = 0 ; $x ||= 'vide' ; # x faux => $x = 'vide' $y // = 'vide' ; # y undef => $y = 'vide' . . p. 45 p. 46 Debug : la chasse aux erreurs Plan 1 Introduction à Perl Données Structures de contrôle Fonctions Commandes internes essentielles Entrées/sorties 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées 5 Modules 6 Interactions et communication 7 Incomplétude Les mêmes principes qu’ailleurs s’appliquent : indenter et documenter son code, le modulariser, vérifier les codes de retour des appels de fonctions, etc. test unitaires ? Mais si on a tout de même une erreur : Utiliser ”perl -w” ou use warnings; use diagnostics; use Data::Dumper; warn Dumper(\@mavariable); use strict; ”perl -d script.pl” : le debugger . . p. 47 p. 48 Définition Arguments et variables locales Une variable locale est crée par l’instruction my. On utilise le mot-clé sub. Les arguments sont passés par références (et non par copie) dans le tableau spécial @_. sub fonction { ... } Lecture des arguments La fonction est appelée par fonction(). Exemple de fonction préservant ses arguments : %h = fonction("texte",3); sub fonction { my ($arg1, $arg2) = @_ ; # ... } La fonction peut retourner un argument avec return. # !/usr/bin/perl -w sub true { return "Vrai" ; } print true(); . Les arguments $_[0] et $_[1] sont ici copiés dans 2 variables locales. shift(@_) est souvent utilisé pour lire (et dépiler) un argument. . . p. 49 p. 50 Arguments et variables locales (2) Exercices . Pourquoi ne peut-on pas recevoir comme arguments deux tableaux distincts ? 2. Écrire une fonction qui affiche ”Vrai” si son argument est vrai, Toute modification des éléments de @_ modifie les arguments qui doivent donc être des variables. sub modifie { $_[0] .= "\n" ; } modifie("Un texte constant"); modifie($a); 1 faux sinon. Proposer une variante syntaxique. Tester avec (2x3-1<13**2). # ERREUR # OK . Que fait la fonction suivante ? sub fonction { my @array = @_ ; foreach (@array) { $_++ ; } return @array ; } .4 Que fait la fonction suivante ? 3 Il appartient à la fonction de choisir si elle copie ses arguments, ou si elle les modifie directement comme ci-dessous. sub upcase_array { foreach $txt (@_) { $txt = uc($txt); } } @a = qw(conte bruit fureur) ; upcase_array(@a); # @a = qw(CONTE BRUIT FUREUR); . sub fonction { foreach (@_) { $_*=2 ; } } . p. 51 p. 52 Plan 1 . Affichage Introduction à Perl Données Structures de contrôle Fonctions Commandes internes essentielles Entrées/sorties 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées 5 Modules 6 Interactions et communication 7 Incomplétude print Affiche ses arguments sur la sortie courante. print 'Je me cache ', $ici, " ou ${la}." ; printf Idem que pour le C. printf "La racine de %d est environ %5f.\n", 3, sqrt(3); warn et die Affiche un texte sur le canal d’erreur (puis quitte). Si l’argument ne se termine pas par \n, insère un warning ad hoc. die "Le programme a besoin d'un argument.\n" unless @ARGV ; warn "Is there a bug here ?" if $debug ; . . p. 53 p. 54 Chaînes de caractères Tableaux (1) Piles chop et chomp 1 push @a, (2,3); $last=pop @a; Exemple : $saisie = <STDIN> ; chomp($saisie); unshift @a, (0); $first=shift @a; Attention : écrire chomp($saisie) ; Attention : et non $saisie=chomp($saisie); 1 2 0 −→ 0 ←− 1 2 1 2 ←− 2 3 −→ 3 1 2 3 1 2 0 1 2 1 2 Inverser une liste reverse renvoie la liste dans l’ordre inverse. @a = reverse (1 .. 10); Sous-chaînes : substr Syntaxe : substr TEXTE,POSITION,TAILLE $t="Un texte long" ; $extrait = substr $t, 3, 5 ; substr($t,3,5)="commentaire" ; 1 @a=(1); chop retire le dernier caractère d’une chaîne. chomp retire le retour à la ligne final, s’il y en a un. Trier une liste Par défaut, sort trie selon l’ordre lexicographique. @a = sort (glob "*"); @a contient la liste triée des fichiers du répertoire courant. # $extrait = "texte"; # $t="Un commentaire long"; . . p. 55 p. 56 Tableaux (2) Exercices . Lire des nombres passés en argument au programme et en afficher la liste triée du plus grand au plus petit sous la forme ”25 > 17 > 12 > 9 > 5 > 2”. 2. Calculer l’intersection de deux tableaux. 1 Tableaux et chaînes de caractères join fusionne une liste en une chaîne. Syntaxe : join TEXTE,LISTE @a = qw(un deux trois) ; $t = join(" ",@a); $t = join(" - ",@a); @a = (1..20); @b = (-1,2,5,7,22,18); ... @intersection = (2,5,7,18); # $t = "un deux trois"; $t="@a"; # $t = "un - deux - trois" . Calculer le produit scalaire de 2 vecteurs. On lira les vecteurs sous la forme v0 ,v1 ,v2 ,… 4. Lister les clés d’un hash associées à une valeur donnée en 3 split découpe une chaîne en une liste. Syntaxe : split REGEXP,TEXTE $t = "un - deux - trois" ; @a = split / - / ,$t ; # @a = ("un","deux","trois") @b = split // ,"lettres" ; # @b = qw(l e t t r e s) . argument. Exemple : %h = ( "un"=>1, "deux"=>2, "Un"=>1 , "aussi"=>1); ./clefs.pl 1 devra afficher 'aussi' 'Un' 'un'. . . p. 57 p. 58 Plan 1 . Ouvrir un fichier Syntaxe : open($FILEHANDLE,"nomdefichier"); Remarques : Par défaut, ouverture en lecture. Avant Perl v5.8, on écrivait FILEHANDLE (non scalaire). Introduction à Perl Données Structures de contrôle Fonctions Commandes internes essentielles Entrées/sorties 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées 5 Modules 6 Interactions et communication 7 Incomplétude Droits d’accès Syntaxe : open($FILEHANDLE, "permissions", "fichier"); Si le nom de fichier est précédé de <, >, >>, >+, le fichier est ouvert resp. en lecture, écriture, ajout, lecture/écriture. open $LOG, "<", "/var/log/dmesg" or die "Erreur d'ouverture de dmesg : $ !" ; # ... acces au fichier ... close $LOG ; STDIN, STDOUT et STDERR sont des descripteurs de fichiers ouverts par défaut. . p. 59 p. 60 Accès en lecture aux fichiers Accès en écriture aux fichiers opérateur <FILEHANDLE> Chaque accès scalaire lit une ligne et passe à la suivante. print, printf while ($ligne = <$FILE>) { print ++$k, ": ", $ligne ; Par défaut, Perl écrit sur STDOUT. Pour écrire dans le fichier pointé par FILEHANDLE, il faut utiliser print FILEHANDLE "...";. } Le retour à la ligne fait partie de la ligne lue (cf chomp). Exemple d’écriture dans un fichier. read open $FILE, ">", "fichier" or die $ ! ; print STDERR "Ecriture en cours..." ; print $FILE "Contenu du fichier :\nPas grand-chose.\n" ; close $FILE ; Syntaxe : read FILEHANDLE,SCALAIRE,TAILLE,OFFSET Syntaxe : read FILEHANDLE,SCALAIRE,TAILLE Renvoie le nombre de caractères lus. open $FILE, "fichier" or die ; read $FILE, $length, 1 ; read $FILE, $pstring, $length ; close $FILE ; . . . p. 61 p. 62 L’opérateur diamant : <> Exercices Un filehandle vide agit comme un filtre. . Lire /etc/passwd et produire un hash %root contenant des clés ”home”, ”shell”, ”UID”, ”GID”. Interroger ce hash. . Écrire un filtre qui compte le nombre de lignes et le nombre de 1 # !/usr/bin/perl -w while ($txt = <>) { print uc($txt); } 2 caractères. . Écrire un programme qui copie un fichier vers un autre, ligne par ligne. 4. Écrire une procédure de sauvegarde de hash et une procédure 3 L’opérateur <> lit depuis les fichiers en arguments, s’ils existent, l’entrée courante, sinon. de lecture de hash dans un fichier. . Écrire un programme qui affiche la fréquence des mots dans un fichier. 6. Construire une fonction multiprint($texte, 5 Alors sont équivalents ./diamant.pl fichier.txt cat fichier.txt |./diamant.pl $filehandles…) qui écrive un texte dans plusieurs fichiers. Et ./diamant.pl sans argument attendra une saisie utilisateur. . . p. 63 p. 64 Exemple complet d’E/S Plan Exemple complet d’E/S : copie de fichier # !/usr/bin/perl use strict ; use warnings ; my ($from, $to) = @ARGV ; open $FROM, "<", $from or die $ ! ; open $TO , ">", $to or die $ ! ; my $line ; while ($line = <$FROM>) { print $TO $line ; } . . 1 Introduction à Perl 2 Premiers pas en Perl Exemple Patterns Match Substitution Techniques avancées 3 Expressions régulières 4 Références et structures de données avancées 5 Modules 6 Interactions et communication 7 Incomplétude . p. 65 p. 66 Documentation Exemple Manuel Perl Comment définir un motif qui permette de reconnaître une adresse électronique ? Plus précisément, comment savoir si un scalaire $email est une adresse email. Quick Start man perlrequick Tutoriel man perlretut Critère 1 : $email doit contenir un @. En général, une expression régulière s’écrit entre deux /, donc /@/ Résumé man perlreref Critère 2 : plus précisément, elle doit contenir @XXX.XX. Un caractère quelconque s’écrit ., donc /@...\.../ Syntaxe des expressions régulières man perlre Opérateurs Perl, section regexp man perlop Critère 3 : le nombre de caractères qui suit @ n’est pas fixé. Un caractère est supposé répété à loisir s’il est suivi de +, donc /.+@.+\..+/ FAQ spéciale regexp man perlfaq6 . . p. 67 p. 68 Exemple (suite) Éléments d’une regexp Critère 4 : les caractères utilisés sont des lettres minuscules. Une liste de caractères est donnée par [abcde], abrégée en [a-e], donc /[a-z]+@[a-z]+\.[a-z]+/ Éléments simples Beaucoup de caractères se désignent eux-même (”A”, ”b”, ”5”). Le ”.” désigne un caractère quelconque. Exemples : Critère 5 : il ne doit pas y avoir d’autres caractères avant ou après. Un ^ initial et un $ final marquent les extrémités de la chaîne. /^[a-z]+@[a-z]+\.[a-z]+$/ . Ce qui donne que $email doit Commencer… (^) par une ou plus lettres minuscules ([a-z]+) suivies d’un arobase (@) suivi de lettres ([a-z]+) suivies d’un point (\.) suivi de lettres ([a-z]+) que rien ne suit ($) /abc/ /a.c/ # le texte contient ”abc” # le texte contient ”a”, un caractere , ”c” Classe de caractères Un caractère parmi une liste s’écrit [...]. Exemples : /[abcd]/ /[a-d]/ /[a-zA-Z]/ . # le texte contient ”a” ou ”b” ou ”c” ou ”d” # idem # le texte contient une lettre ascii . p. 69 p. 70 Éléments d’une regexp (2) Éléments d’une regexp (3) Classe de caractères Multiplicateurs Pour une négation de classe, il faut placer un ^ en début de liste. Combien de fois doit apparaître un caractère ? ? 0 ou 1 répétition de la classe de caractère précédant * 0 ou + répétition de la classe de caractère précédant + 1 ou + répétition de la classe de caractère précédant {i,j} i à j répétition de la classe de caractère précédant (par défaut, si j est absent, j = ∞) Exemples : /a[^b]c/ # rejette ”abc” et accepte ”aac”, ”a0c”, ”balcon” /[a-z][^0-9]/ # rejette ”l33t” et accepte ”1eet” Classes prédéfinies . \d \w \s [0-9] [a-zA-Z0-9_] [ \r\t\n\f] Tout caractère Chiffres Alphanumériques (et _) Espaces Exemples /tions?$/; /^ \s*a+/; /^ 1.{0,4}2$/; On peut combiner : /[\d\s_-]/ exemples de textes correspondants ”intuition”, ”mentions”, ”ration” ” a”, ”aaa”, ” ab” ”12”, ”1abcd2”, ”1aaa2”, ”1a !2” Les négations existent :\D, \W, et \S. . . p. 71 p. 72 Exercices Interpolation dans une regexp Variables Un $ qui n’est ni protégé par \ ni placé en fin d’expression indique un nom de variable. . Que donnent les regexps suivantes sur les textes en vis-à-vis ? /a.[ˆc]/ ”pacte”, ”barque !”, ”talc”, ”archaïque” /e.+u$/ ”perdure”, ”feu”, ”e-sudoku”, ”repu” /\w+\s?\ ?/ ”Ano- ?”, ”Oui ?”, ”No !”, ”Errr ?” /^#!\s*\S+$/ ”# !/bin/sh”, ”# !/usr/bin/perl -w” $a='[a-z]\d' ; /$a$/; # idem /[a−z]\d$/ 1 Le motif est parcouru à la façon de "…". /\n\t\e/ # newline, puis tabulation , puis escape /\Q\n\t\E\e/ # \n\t puis escape $motif="a" ; /\U$motif\E/; # /A/ . . . p. 73 p. 74 Matching : m/.../ Exercices Comment appliquer une regexp ? . Écrire un programme qui reçoit en argument une regexp de matching et teste cette regexp sur chaque ligne lue. 2. Proposer et tester, à l’aide du script 1, des regexp qui reconnaissent 1 On utilise l’opérateur =~. if ($txt =~ /a/) { print "\$txt contient un 'a'.\n" ; } une ligne vide. une ligne vide, en dehors d’éventuels espaces. une phrase (majuscule initiale et ponctuation finale). au moins un ”a” suivi d’au plus un ”s”. Il y a d’autres types de regexp. Pour mieux préciser qu’il s’agit de matching, on peut écrire : $txt =~ m/a/ . Écrire une fonction qui teste si une chaîne est un entier naturel, un réel, ou n’est pas un nombre. 4. Tester si une chaîne est valide comme (ancien) numéro Une regexp sans opérateur est appliquée à $_. 3 foreach (@tableau) { print if /\n$/; } d’immatriculation de véhicule. . . p. 75 p. 76 Substitution : s/motif/remplacement/ La gourmandise Quand on applique un multiplicateur, il est gourmand (greedy) par défaut : il capte autant de caractères que possible. Le second membre remplace la correspondance obtenue par le motif. Application avec =~ comme pour le matching. $_ = "aaabbb" ; s/b+/B/; s/.*/!/; Exemples $_ = "Lapin" ; s/a/u/; # s/^./R/; # s/[A-Z].//; # s/^/Sa/; # . # $_ = ”aaaB” ; # $_ = ” !” ; Les multiplicateurs peuvent être non-gourmands (sobres ?) s’ils sont suivis d’un ” ?” : on obtient *?, +?, et {i,j} ?. ”Lupin” ”Rupin” ”pin” ”Sapin” $_ = "aaabbb" ; s/b+?/B/; s/.* ?/!/; . # $_ = ”aaaBbb” ; # $_ = ” !aaaBbb” ; . p. 77 p. 78 Exercices Modificateurs $_ = "Karamazov" ; s/a/o/; # ”Koramazov” !!! s/a/o/g ; # ”Koromozov” . Proposer et tester une substitution qui 1 efface le premier caractère transforme ”barbare” en ”tartare”. Principaux modificateurs . Écrire une fonction qui supprime les blancs de début et de fin de ligne pour le texte passé en argument. 3. Remplacer ”oui” par ”non” quelle que soit la casse du premier. 2 g i m s . Écrire un filtre qui reçoit en argument une regexp de substitution et l’applique à chaque ligne. On utilisera la fonction eval(". . ."). .5 Écrire une variante de l’exercice 4 qui reçoive une chaîne (et non un motif) à remplacer et sa substitution. Par exemple, "a.b" et "XXX" transformera "arba.b" en "arbXXX". 4 global (toutes les occurrences) insensible à la casse multiligne (^ et $ pour le début et la fin de chaque ligne) single-line (tout le texte considéré comme une seule ligne) while (m/lapin/g) { print "Encore un lapin !\n" ; } s/\n\n+/\n/gs ; . # efface les retours chariot multiples . p. 79 p. 80 Groupes Traduction : tr/.../.../ Alternatives Comment avoir le choix dans une regexp ? /chaud|froid/ est identique à /chaud/ or /froid/. /apostats?|apocalypses?/ correspond à 4 mots. Remplace caractère par caractère. Renvoie le nombre de remplacements. Groupes $_ = "Philistins" ; Les parenthèses ( ) permettent de regrouper des termes. /apo(stat|calypse)s ?/ /(pa)?radis/ # /paradis| radis / /ar(br|me)(e|ment)/ # arbre, armee, arbrment, armement tr/Pi/ Co/ ; print ; Mémoire Chaque correspondance à un groupe est stockée dans une variable $1, puis $2, etc. s/apo(stat|calypse)s ?/$1/ # remplacera apostat par stat s/(anti|pro)-nucleaire(s ?)/$1-centrale$2/ . # Cholostons tr/a-zA-Z/ A-Za-z/ ; print ; # cHOLOSTONS . . p. 81 p. 82 Découper une chaîne : split Exercices . Proposer et tester une regexp qui 1 échange les deux premiers mots du texte insère une espace (s’il n’y en a pas) avant les signes ” ; : ? !” convertit une date ISO au format français (par exemple de 2005-12-30 à 30 décembre 2005) enlève les accents dans un texte split est bien plus que la fonction réciproque de join. Syntaxe : split REGEXP,TEXTE $txt = "a=>b => c ===> d" ; @termes = split /\s*=+>\s*/ ,$txt ; print "@termes\n" ; # a b c d . Programmer un filtre qui compte le nombre de signes de ponctuation. 3. Écrire un filtre comptabilisant le nombre d’occurrences d’un 2 motif passé en argument. . Convertir toutes les balises HTML d’un fichier en majuscules. 4 . . p. 83 p. 84 Plan Références Une référence est un scalaire. C’est en quelque sorte un pointeur à la Perl. $reference −→ données 1 Introduction à Perl 2 Premiers pas en Perl 3 Expressions régulières Définition 4 Références et structures de données avancées 5 Modules 6 Interactions et communication Préfixer par un $ déréférence le scalaire. 7 Incomplétude print $$rt ; $$ra1 = 1 ; Références à des scalaires Préfixer par un \ référence la variable scalaire. $t="Ahem" ; $rt=\$t ; @a=(1,2,0); $ra1=\$a[1]; Déréférencement # print "Ahem"; ($$rt idem $t) # $a[1]=1; Pour un scalaire : $reference −→ $scalaire=$$reference . . . p. 85 p. 86 Références à des tableaux Références à des hashes De façon identique, \@a référence le tableau @a. $ra1 = \@array ; foreach $x (@$ra1) { ... } # idem : foreach $x (@array) ATTENTION : ”\” s’applique à une variable ! ATTENTION : En effet : \($a,@b) ↔ (\$a,\@b). À partir d’une variable, avec \%hash. Directement (hash anonyme), avec $rh = { ...}. $rhash = { "Russie" => "Moscou", "Japon" => "Tōkyō �� ", }; foreach $pays (keys %$rhash) { print "$pays : Capitale $rhash->{$pays}\n" ; } Tableaux anonymes Les crochets [ ] construisent directement une telle référence. $ra2 = [1, 2, [9,8,7], $ra1]; Déréférencement des éléments avec -> print print print print print $$ra2[0]; $ra2->[1]; $ra2->[2]->[0]; $ra2->[2][1]; "@{$ra2->[2]}" ; # # # # # 1 2 9 8 9 8 7 (idem ${$ra2}[0]) (notation) C’est cette syntaxe qui permet d’écrire des enregistrements (les ”struct” du C). (simplification) . . p. 87 p. 88 Utilisation de références Exercices . Comparer \@a et [@a]. Commenter alors le code suivant : @a = (1,2,3); $r1 = [@a]; push @$r1, 4 ; $r2 = \@a ; shift @$r2 ; 2. Écrire une fonction qui lit deux tableaux et renvoie les Passage d’arguments à une fonction 1 Comment créer une fonction qui renvoie l’intersection de 2 tableaux ? sub intersecte { (@a,@b) = @_ ; # ERREUR !!! if ($a[0] == $b[0]) { éléments du premier que ne sont pas dans le second. . Écrire un programme qui saisisse ligne par ligne un tableau à deux dimensions, puis demande quelle ligne afficher. 4. Reprendre l’exemple précédent et contruire une variable qui Il faut passer des références aux tableaux. sub intersecte { ($a,$b) = @_ ; if ($a->[0] == $b->[0]) { ... } 3 stocke les lignes et les colonnes du tableau. . Stocker dans un hash anonyme les informations de /etc/passwd et y accéder à la demande (en choisissant parmi les logins, puis parmi les champs uid, gid, home, shell). 5 @inter = intersecte(\@tab1,\@tab2); . . . p. 89 p. 90 Plan Utilisation d’un module 1 Introduction à Perl 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées Utilisation CPAN Création de bibliothèques de code et de modules 5 Modules 6 Interactions et communication 7 Incomplétude Exemple # !/usr/bin/perl -w use LWP::Simple ; $content = get("http://perl.org/"); die "Erreur web ?" unless defined $content ; print "$1\n" if ($content =~ m/(Copyright[\s\d-]+)/ ); Télécharge la page web grâce à la fonction get() du module LWP::Simple, et affiche son copyright. Principe La directive use Module; déclare l’utilisation du module. Un man Module est fortement recommandé. Ce use est traité à la compilation, pas à l’exécution. . . p. 91 p. 92 Le module Getopt Modules à syntaxe objet Certains modules sont seulement objet, d’autres laissent le choix. # ! /usr/bin/perl -w use Getopt::Long qw(:config bundling) ; use XML::Simple ; my $hashref = XMLin("dico.xml"); foreach $k (keys %$hashref) { $hashref->{$k} =~ s/\s+$// ; } XMLout($hashref, OutputFile => "dico_2.xml"); # initialisation des options : valeurs par defaut %opts = ( verbose => 0, ^^I debug => 0 ); # lecture des options GetOptions(\%opts, ^^I "help|h", # "script.pl --help" ou "-h" ^^I "verbose|v+", # $opts{verbose} ^^I "configfile|config|c=s"); Et en version objet : use XML::Simple ; my $obj = new XML::Simple ; my $hashref = $obj->XMLin("dico.xml"); foreach $k (keys %$hashref) { $hashref->{$k} =~ s/\s+$// ; } $obj->XMLout($hashref, OutputFile => "dico_2.xml"); foreach (@ARGV) { if (-d) { push @directories,$_ ; next ; } die "Argument non compris : $_\n" ; } . . . p. 93 p. 94 Trouver le module souhaité Exercices Distribution spécifique Debian : 1668 paquets dans la distribution Debian Lenny. Windows : 7870 modules dans ActivePerl. . Utiliser XML::Simple pour sauvegarder et charger un hash dans un fichier. 2. Écrire un programme qui affiche les titres du Monde en ligne 1 CPAN cpan.org centralise des milliers de modules. (www.lemonde.fr) en utilisant le module LWP::Simple. . On souhaite que les éléments d’un hash respectent l’ordre dans lequel ils ont été créés. Touver la méthode dans la doc de Perl, puis la mettre en place à l’aide de CPAN. Exemples de modules utiles 3 Data ::Dumper # pour savoir ce que contient une variable Getopt ::Long # pour traiter facilement les arguments et options Pod ::Usage # pour documenter son programme XML ::Simple # pour les manips simples en XML Template # pour remplir des templates en Perl File ::Find # pour naviguer dans l ’ arborescence LWP ::Simple # pour les acces web simples . . p. 95 p. 96 Inclusion de fichiers de code # !/usr/bin/perl Packages et espaces de nommage require "include.pl" ; print $truc ; printdate(); $truc = "chose\n" ; sub printdate { # ... } 1; script.pl include.pl Remarques package Machin ; $truc = "chose\n" ; sub printdate { } 1; script.pl include.pl Remarques require "filename" cherche le fichier dans les chemins du tableau @INC. Pour le modifier : push @INC, "/my/path". Par défaut le code est dans package main; Pour accéder à une variable globale masquée : $variable = 5 ; sub fonction { my $variable ; print $main::variable ; } Les répétitions de require sont ignorées. Tout fichier inclus se termine par 1; Inconvénient Risque de collusions de variables ou de fonctions ! . require "include.pl" ; print $Machin::truc ; Machin::printdate(); # !/usr/bin/perl . . p. 97 p. 98 Portée des variables Modules : importation Un module peut ajouter des symboles dans main::. # !/usr/bin/perl use English ; # charge le module English.pm use Carp qw(croak) ; # importe seulement croak() use Benchmark (); # pas d'import croak("no"); # importé dans main:: Benchmark::timethese( ... ); # pas dans main:: Que se passe-t-il si on passe en use strict ? Il faut déclarer les variables ! Dans un fichier inclus : my ne peut pas sortir du fichier de déclaration. our déclare une variable globale : # !/usr/bin/perl use strict ; require "include.pl" ; print $Machin::truc ; Machin::printdate(); package Machin ; our $truc = "chose\n" ; sub printdate { } 1; script.pl include.pl use versus require use est lancé lors de la compilation, require à l’exécution. use peut importer des symboles. require Module charge le module, mais sans import de symboles. Attention : require Term::Readline ⇐⇒ require "Term/Readline.pm" . . p. 99 p. 100 Créer un module package Mon::Module ; Plan # fichier Mon/Module.pm 2 4 1 Introduction à Perl 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées 5 Modules Interfaces Système ... 6 Interactions et communication END { ... } # destructeur global (en fin de programme) 7 Incomplétude use strict ; use Exporter ; our @ISA = qw(Exporter) ; 6 8 10 12 # variable globale accessible par $Mon::Module::VERSION our $VERSION = 0.1 ; # symboles exportés automatiquement our @EXPORT = qw(&fonction1 &fonction2) ; # symboles exportables à la demande our @EXPORT_OK = qw($var1 %hash1 &fonction3) ; 14 16 18 . 1; . . p. 101 p. 102 Interfaces utilisateurs Perl et le système de fichiers Lister les fichiers Curses (mode texte) Tk (interface historique) Gtk (linux) / wxWidgets (wxPerl) glob renvoie une liste de fichiers correspondant à un motif shell. @header_files = glob "*.h" ; Exemple de Perl/Tk Tests de fichiers use strict ; use Tk ; my $mainWin = new MainWindow ( -title => 'Hello' ) ; $mainWin->Label( -text => 'Hello, world!' )->pack(); MainLoop(); . use Tk ; use Tk::LabEntry ; $main = new MainWindow(); my $dial=$main->LabEntry(-width => 50, -label=>"RegExp :", -textvariable => \$op); $dial->pack(-fill => 'x', -expand => 0); $main->Button(-text => 'Renommer', -command => \&renommer )->pack ; MainLoop ; La syntaxe générale est -x "nomdefichier". Quelques opérateurs : -e existence -x droits d’exécution -s taille en octets -f fichier -r droits en lecture -M âge (en jours) -d répertoire -w droits en écriture -f -x (≥ v5.10) … if ($arg and -d $arg) { foreach my $file (glob "$arg/*.pl") { print "Perl file: $file\n" ; } } . p. 103 p. 104 Exécuter un programme externe Exercices system exécute et attend la fin du programme appelé. system("ls -1sh"); system("ls", "-1", "-sh"); # passe par un shell # sans shell . Afficher tous les fichiers exécutables de /bin/, triés selon leur taille. Puis optimiser pour ne demander la taille qu’une seule fois par fichier. 2. Écrire un programme qui change les droits d’accès pour toutes 1 Les backquotes renvoient le texte produit par une commande. $fichiers = `ls -1` ; @files = split /\n/ ,$fichiers ; les entrées dans un répertoire donné. . Reprendre le programme précédent pour permettre de donner des droits différents aux fichiers et aux répertoires. 4. Ajouter une option récursive au programme précédent grâce à File::Find. 3 Attention : Ce n’est ni fiable, ni portable. Rediriger la sortie du programme avec open. open LS, "ls -1|" or die "ERREUR $ !" ; my @files = <LS> ; . . . p. 105 p. 106 Les bases de données Exemple MySQL use DBI ; my $DB_NAME = "produits" ; my $DB_USER = "user" ; my $DB_PASSWD = "password" ; my $dbh = DBI->connect( "DBI:mysql:$DB_NAME", $DB_USER, $DB_PASSWD) or die "Erreur lors de la liaison avec la DB : $ !" ; Le module DBI (DataBase Independant for Perl) permet l’accès aux bases de données. La syntaxe est commune à toutes les bases de données acceptées par DBI : MySQL, PostgreSL, Oracle… Attention : la compatibilité du SQL n’est pas garantie ! $req = $dbh->prepare("SELECT foo, bar ". "FROM table WHERE baz=?"); $req->execute( $baz ); while ( @row = $req->fetchrow_array ) { print join(" | ", @row), "\n" ; } $dbh->disconnect ; Documentation perldoc DBI pour l’utilisation générale. DBD::mysql pour le ”driver” MySQL. DBD::SQLite pour le ”driver” SQLite, etc. . . p. 107 p. 108 Exercices Plan . Utiliser le module DBI avec le driver SQLite (DBD::SQLite) pour créer une base base et une table passwd. Remplir cette dernière avec le contenu de /etc/passwd. Le SQL nécessaire : CREATE TABLE passwd ( login, x, uid, gid, description, home, shell ) INSERT INTO passwd VALUES (...) SELECT * FROM passwd WHERE ... 1 Introduction à Perl 2 Premiers pas en Perl 3 Expressions régulières 4 Références et structures de données avancées 5 Modules 6 Interactions et communication 7 Incomplétude Ce qu’il reste à découvrir Bibliographie 1 . . . p. 109 p. 110 Quelques thèmes non abordés Bibliographie choisie Introduction à Perl, alias Le lama. 286 pages, 4e édition, 2006. Éditions O’Reilly France. Traduction de Learning Perl de Schwartz, Phoenix, Foy. le débuggeur Perl (perl -d) la syntaxe étendue des expressions rationnelles Perl moderne, de Bruhat et al. 464 pages, 1re édition, 2010. Éditions Pearson. l’interfaçage avec d’autre langages la gestion des processus (Poe) Perl pour l’impatient de Desreux, Tougard. 128 pages, 2e édition, 2005. Éditions H&K. la programmation objet (Moose) les monolignes (les options CLI avec man perlrun) En anglais : le format de documentation POD Perl Cookbook de Tom Christansen. 976 pages, 2nd edition, 2003. O’Reilly. Les nouveautés de Perl 5.10 sq. (man perl5100delta) Modern Perl (en ligne, licence Creative Commons) Et beaucoup de détails : opérateurs, variables prédéfinies, … http://www.onyxneon.com/books/modern_perl/index.html Beginning Perl, publié en 2000. http://www.perl.org/books/beginning-perl/ . . p. 111 p. 112 Obfuscative code Japh Mode lancée par Randal L. Schwartz pour ses signatures dans les newsgroups. Exécutable en Perl et en postscript. /;{}def/ #{def}def/$_={/Times-Bold exch selectfont}#/_{rmoveto}#/"{dup}#/*/!/$ ;/q{exch}#/x ; {/J q #}#/ .{/T q #}#{stringwidth}#{}#{}# 14 string dup dup dup 260 40 moveto 90 rotate ; %/}} ;$0='"\e[7m \e[0m"' ;@ARGV=split// ,reverse q(ThePerl). q(Journal) x 220 ; q ; 0 T putinterval exch 7 J putinterval ; ; $_= q /m$ pop T($* !$"=!$ " )pop " * true% ? $ " $ !" " !! !! % !" !" ! ! charpath { !"""}pop $ pop{""!}pop ! neg{ !#}pop 220 ! neg _{ !!}pop J false %T charpath clip " pop 0 " moveto 6{ !!}pop $_= 105{ !!}pop {$ ! $ " ! # ! ##} pop{dup dup $ ! " pop pop q{"}pop 22{dup show}repeat {"}pop q 22 mul{$ "} pop neg{ !# ! $ "}pop ! 8 .65 mul{$ # # $}pop ! neg{"}pop _ pop{"}pop } repeat pop " { $ " ! ! ! $ " ! !" "#" #"!"""""! #" " # "m/ ;@ARGV=(@ARGV[-14..-1])x50 ;q} 0 "%} ;s/m[ou]|[-\dA-ln-z.\n_{}]|\$_=//gx ;s/(.)(?{$*=''})/('$*.='.(++$# %2?'':"$0;").'pop;')x(ord($1)-31).'$*'/gee ;s/((.(\e\[.m)*|.){77})/$1\n/g ;print ; sub showpage {} $,=" " ;print +("hacker,","Just","Perl","another")[1,3,2,0]; print grep(s/\d// , sort(split "8hacker, 4Perl 1Just 2another")); $_="krJhruaesrltre c a cnp,ohet" ; $_.=$1,print$2 while s/(..)(.)// ; $_='x"Not ";"x\"another \";\'x\\"perl \\";x\\"hacker,\\"\'"' ; s/x/print/g ;eval eval eval ; $_ = "wftedskaebjgdpjgidbsmnjgc" ; tr/a-z/oh, turtleneck Phrase Jar !/ ; print ; . . . p. 113 p. 114 Perl golf Informations utiles Principe Résoudre un problème avec le programme le plus court possible. Pour garder le contact : [email protected] Exemple 1 Convertir le nombre donné en argument de base 36 en base 10. map$.=36*$.-55+/\d/*7+ord,pop=~/./g ;print$..$/ Les documents utilisés sont disponibles en ligne : http://silecs.info/formations/Perl/ Transparents Exemple 2 Afficher l’ensemble de Cantor au rang donné en argument ; Corrections des exercices s/./$& $&/g for($\="-")x pop ;print Documents de référence Exécution avec les arguments 1, puis 2, puis 3. - - - - - - - - - - - . . p. 115 Licence Copyright (c) 2007-2013 François Gannaz ([email protected]) Permission vous est donnée de copier, distribuer et/ou modifier ce document selon les termes de la Licence GNU Free Documentation License, Version 2.0 ou ultérieure publiée par la Free Software Foundation ; pas de section inaltérable ; pas de texte inaltérable de première page de couverture ; texte inaltérable de dernière page de couverture : « Auteur : François Gannaz <[email protected]> » . .