Outils pour utilisateurs

Outils du site


perl:variables_et_structures_de_donnees

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
perl:variables_et_structures_de_donnees [2009/03/15 00:40] – édition externe 127.0.0.1perl:variables_et_structures_de_donnees [2013/03/12 23:40] (Version actuelle) root
Ligne 1: Ligne 1:
-====== 1. Généralités sur les variables ======+====== Généralités ====== 
 + 
 +====== 1. Les variables ======
  
 ===== Nommage ===== ===== Nommage =====
Ligne 9: Ligne 11:
  
 Dans le style de programmation Perl traditionnel, on utilise les minuscules pour les noms de variables. Une variable commence par un caractère qui détermine son type, et qui ne peut qu'être **$** (dollar), **@** (arobase) ou **%** (pourcent) : Dans le style de programmation Perl traditionnel, on utilise les minuscules pour les noms de variables. Une variable commence par un caractère qui détermine son type, et qui ne peut qu'être **$** (dollar), **@** (arobase) ou **%** (pourcent) :
 +<code perl>
   $scalaire = "bonjour";   $scalaire = "bonjour";
   @liste = ("bonjour", 1, "monde");   @liste = ("bonjour", 1, "monde");
   %hash = ("message" => "bonjour");   %hash = ("message" => "bonjour");
 +</code>
  
 En Perl, on peut utiliser le même nom de variable pour des types de différents de manière indépendante. Par exemple, ces 3 variables co-existent et sont indépendantes : En Perl, on peut utiliser le même nom de variable pour des types de différents de manière indépendante. Par exemple, ces 3 variables co-existent et sont indépendantes :
 +<code perl>
   $toto = "bonjour";   $toto = "bonjour";
   @toto = ("bonjour", 1, "monde");   @toto = ("bonjour", 1, "monde");
   %toto = ("message" => "bonjour");   %toto = ("message" => "bonjour");
 +</code>
  
 **Note**: il existe quelques exceptions notables, dont le descripteur de fichier qui n'a pas de préfixe particulier et utilise traditionnellement des majuscules (ex: open(HANDLE, "hello.txt")). **Note**: il existe quelques exceptions notables, dont le descripteur de fichier qui n'a pas de préfixe particulier et utilise traditionnellement des majuscules (ex: open(HANDLE, "hello.txt")).
Ligne 23: Ligne 29:
  
 Les variables en Perl n'ont pas besoin d'être déclarées et son globales par défaut. Comme leur type fait partie de leur nom (via le symbole préfixe ad hoc), ceci est justifiable : Les variables en Perl n'ont pas besoin d'être déclarées et son globales par défaut. Comme leur type fait partie de leur nom (via le symbole préfixe ad hoc), ceci est justifiable :
 +<code perl>
   for ($i = 0; $i < 5; $i++) { ... }   for ($i = 0; $i < 5; $i++) { ... }
 +</code>
  
 Cependant, en pratique et notamment lorsqu'on introduira les fonctions et les modules, nous verrons qu'il s'agit d'une pratique peu fiable et à proscrire. On va alors prendre l'habitude de déclarer nos variables : Cependant, en pratique et notamment lorsqu'on introduira les fonctions et les modules, nous verrons qu'il s'agit d'une pratique peu fiable et à proscrire. On va alors prendre l'habitude de déclarer nos variables :
 +<code perl>
   use strict;   use strict;
   my $i;   my $i;
   for ($i = 0; $i < 5; $++) ...   for ($i = 0; $i < 5; $++) ...
 +</code>
  
 **Note**: la directive **use strict** dans le dernier exemple indique au compilateur de Perl que nous voulons vérifier que toutes les variables utilisées sont bien déclarées au préalable, et générer une erreur le cas échéant. **Note**: la directive **use strict** dans le dernier exemple indique au compilateur de Perl que nous voulons vérifier que toutes les variables utilisées sont bien déclarées au préalable, et générer une erreur le cas échéant.
Ligne 35: Ligne 45:
  
 Une variable peut ne pas avoir de valeur, elle est alors **indéfinie** (on pourrait dire non **initalisée** pour comparer au C). Cela veut dire que d'une part une "non-valeur" est représentable en Perl, mais en plus que nous pouvons mettre à contribution l'interpréteur pour détecter les variables qui sont utilisées sans être initialisées. C'est ce que l'on fait souvent en utilisant l'option **-w** de Perl : Une variable peut ne pas avoir de valeur, elle est alors **indéfinie** (on pourrait dire non **initalisée** pour comparer au C). Cela veut dire que d'une part une "non-valeur" est représentable en Perl, mais en plus que nous pouvons mettre à contribution l'interpréteur pour détecter les variables qui sont utilisées sans être initialisées. C'est ce que l'on fait souvent en utilisant l'option **-w** de Perl :
 +<code perl>
   #!/usr/bin/perl -w   #!/usr/bin/perl -w
      
   my $message;   my $message;
   print "message: $message\n";   print "message: $message\n";
 +</code>
  
 ... va générer le //warning// suivant lors de l'exécution: //Use of uninitialized value in concatenation (.) or string at blob line 4.//. Voici une illustration plus complète du cycle de vie d'une variable : ... va générer le //warning// suivant lors de l'exécution: //Use of uninitialized value in concatenation (.) or string at blob line 4.//. Voici une illustration plus complète du cycle de vie d'une variable :
 +<code perl>
   # $toto n'existe pas (encore)   # $toto n'existe pas (encore)
   my $toto; # $toto est déclarée et peut être utilisée, mais n'est pas définie   my $toto; # $toto est déclarée et peut être utilisée, mais n'est pas définie
Ligne 47: Ligne 59:
   $toto = 42; # $toto est définie   $toto = 42; # $toto est définie
   $toto = undef; # $toto n'est plus définie   $toto = undef; # $toto n'est plus définie
 +</code>
  
 **Note**: on ne peut pas "dé-déclarer" une variable ! **Note**: on ne peut pas "dé-déclarer" une variable !
Ligne 58: Ligne 71:
   * une référence (que nous verrons plus tard)   * une référence (que nous verrons plus tard)
  
 +<code perl>
   my $int = 42;   my $int = 42;
   my $float = 42.53;   my $float = 42.53;
   my $string = "Bonjour";   my $string = "Bonjour";
   my $string2 = 'Bonjour';   my $string2 = 'Bonjour';
 +</code>
  
 Perl permet de passer d'une représentation à une autre de manière transparente. Le point délicat consiste à comprendre quand le changement de représentation a lieu: on parle alors de contexte d'une opération. Voici par exemple deux façons de considérer la valeur "0" : Perl permet de passer d'une représentation à une autre de manière transparente. Le point délicat consiste à comprendre quand le changement de représentation a lieu: on parle alors de contexte d'une opération. Voici par exemple deux façons de considérer la valeur "0" :
 +<code perl>
   my $val = 42;   my $val = 42;
   print "la valeur numérique n'est pas nulle" if $val != 0;   print "la valeur numérique n'est pas nulle" if $val != 0;
Ligne 70: Ligne 86:
   my $int = $val + 1; # $int vaut 43   my $int = $val + 1; # $int vaut 43
   my $string = $val . " le monde"; # $string vaut 'Bonjour le monde'   my $string = $val . " le monde"; # $string vaut 'Bonjour le monde'
 +</code>
  
 S'il est toujours possible de transformer une valeur entière en une chaîne de caractère (en utilisant sa représentation décimale, éventuellement en "écriture scientifique"), il n'est toujours évident d'interpréter une chaîne de caractère comme une valeur numérique: si la conversion échoue, Perl utilise la valeur numérique **0**. S'il est toujours possible de transformer une valeur entière en une chaîne de caractère (en utilisant sa représentation décimale, éventuellement en "écriture scientifique"), il n'est toujours évident d'interpréter une chaîne de caractère comme une valeur numérique: si la conversion échoue, Perl utilise la valeur numérique **0**.
 +<code perl>
   print "-42" + 1; # Affiche -41   print "-42" + 1; # Affiche -41
   print "- 42" + 1; # Affiche 1   print "- 42" + 1; # Affiche 1
 +</code>
  
 **Note**: certains opérateurs (comme la division) utilisent un contexte "virgule flottante". Il est possible de forcer globalement le contexte de la plupart des opérations numériques en contexte entier avec la directive //use integer//. **Note**: certains opérateurs (comme la division) utilisent un contexte "virgule flottante". Il est possible de forcer globalement le contexte de la plupart des opérations numériques en contexte entier avec la directive //use integer//.
 +
 +<code perl>
 +my $age = 24;
 +my $majeur = ($age >= 18) ? true : false;
 +</code>
 +
 +$majeur prendra la valeur true car 24 supérieur à 18, dans le cas contraire la variable aurait pris la valeur false.
  
 ===== Opérateurs arithmétiques ===== ===== Opérateurs arithmétiques =====
  
 Leur contexte est bien entendu entier, et tout scalaire impliqué dans une opération arithmétique est (éventuellement) converti en valeur numérique. On retrouve les opérateurs classiques : Leur contexte est bien entendu entier, et tout scalaire impliqué dans une opération arithmétique est (éventuellement) converti en valeur numérique. On retrouve les opérateurs classiques :
 +<code perl>
   $n = ($x / 2 + 5) * 3 - $y;   $n = ($x / 2 + 5) * 3 - $y;
   $n += 10;   $n += 10;
   $n++;   $n++;
 +</code>
  
 Pour comparer des valeurs arithmétiques, on utilise les opérateurs "naturels" : Pour comparer des valeurs arithmétiques, on utilise les opérateurs "naturels" :
-  my $a = 5;+<code perl>  
 + my $a = 5;
   my $b = 9;   my $b = 9;
   print "différence" if $a != $b;   print "différence" if $a != $b;
   print "égalité" if $a ====== $b;   print "égalité" if $a ====== $b;
   print "supériorité" if $a > $b;   print "supériorité" if $a > $b;
 +</code>
  
 ===== Opérateurs de chaîne ===== ===== Opérateurs de chaîne =====
  
 Leur conversion transforme automatiquement toute valeur numérique impliquée en sa représentation décimale. **Note**: si vous voulez plus de contrôle sur cette conversion, il faut l'effectuer explicitement avec //sprintf// (par exemple). Leur conversion transforme automatiquement toute valeur numérique impliquée en sa représentation décimale. **Note**: si vous voulez plus de contrôle sur cette conversion, il faut l'effectuer explicitement avec //sprintf// (par exemple).
 +<code perl>
   $t = "Bonjour";   $t = "Bonjour";
   $t = $t . " le monde";   $t = $t . " le monde";
 +</code>
  
 La plupart des manipulations intéressantes avec les chaînes se font via les expressions régulières. On trouve bien sûr les fonctions basiques comme //length//, //index// et //substr// par exemple. La plupart des manipulations intéressantes avec les chaînes se font via les expressions régulières. On trouve bien sûr les fonctions basiques comme //length//, //index// et //substr// par exemple.
  
 Pour comparer des chaînes, on utilise les opérateurs **eq** et **ne** dédiés à cet effet : Pour comparer des chaînes, on utilise les opérateurs **eq** et **ne** dédiés à cet effet :
 +<code perl>
   my $u = "Paul";   my $u = "Paul";
   my $v = "Pierre";   my $v = "Pierre";
   print "différence" if $u ne $v;   print "différence" if $u ne $v;
   print "identité" if $u eq $v;   print "identité" if $u eq $v;
 +</code>
  
 ====== 3. Les listes ====== ====== 3. Les listes ======
  
 Cette structure de donnée permet à la fois de gérer des tableaux et des listes de façon simple. Les éléments d'une liste en Perl sont des scalaires : Cette structure de donnée permet à la fois de gérer des tableaux et des listes de façon simple. Les éléments d'une liste en Perl sont des scalaires :
 +<code perl>
   my @liste = (1, "bonjour", "etc...");   my @liste = (1, "bonjour", "etc...");
 +</code>
  
 Pour accéder à un élément de la liste, il existe plusieurs moyens : Pour accéder à un élément de la liste, il existe plusieurs moyens :
 +<code perl>
   my $a = shift(@liste); # $a vaut 1   my $a = shift(@liste); # $a vaut 1
   my $b = $liste[0]; # $b vaut "bonjour"   my $b = $liste[0]; # $b vaut "bonjour"
   my $c = $liste[-1]; # $c vaut "etc..."   my $c = $liste[-1]; # $c vaut "etc..."
   my (undef, $d) = @liste; # $d vaut "etc..."   my (undef, $d) = @liste; # $d vaut "etc..."
 +</code>
  
 Pour obtenir la taille d'une liste : Pour obtenir la taille d'une liste :
 +<code perl>
   my $size = @liste;   my $size = @liste;
   my $size = scalar(@liste);   my $size = scalar(@liste);
   my $size = $#liste + 1;   my $size = $#liste + 1;
 +</code>
  
 **Note**: nous reviendrons sur les conversions entre listes et scalaires plus tard. **Note**: nous reviendrons sur les conversions entre listes et scalaires plus tard.
Ligne 127: Ligne 166:
  
   * Méthode alternative pour construire une liste :   * Méthode alternative pour construire une liste :
 +<code perl>
   @liste = qw/Hello world !\n/;   @liste = qw/Hello world !\n/;
   @liste = split(/ /, "Hello world !\n");   @liste = split(/ /, "Hello world !\n");
 +</code>
   * Extraire une partie de la liste (voir //splice// également):   * Extraire une partie de la liste (voir //splice// également):
 +<code perl>
   @extrait = @liste[1..2]; # world, !\n   @extrait = @liste[1..2]; # world, !\n
 +</code>
   * Concaténer les éléments d'une liste (dans un scalaire):   * Concaténer les éléments d'une liste (dans un scalaire):
 +<code perl>
   $phrase = join(' ', @mots);   $phrase = join(' ', @mots);
 +</code>
   * Ajouter un élément à une liste:   * Ajouter un élément à une liste:
 +<code perl>
   push @liste, 'bonjour';   push @liste, 'bonjour';
 +</code>
   * Retirer le premier élément de la liste:   * Retirer le premier élément de la liste:
 +<code perl>
   $element = shift @liste;   $element = shift @liste;
 +</code>
   * Retirer un élément quelconque:   * Retirer un élément quelconque:
 +<code perl>
   delete $liste[2]; # Différent de $liste[2] = undef; !   delete $liste[2]; # Différent de $liste[2] = undef; !
 +</code>
   * Trier une liste:   * Trier une liste:
 +<code perl>
   @direct = sort @liste;   @direct = sort @liste;
   @inverse = sort { ! $a <=> $b } @liste;   @inverse = sort { ! $a <=> $b } @liste;
 +</code>
   * Filtrer une liste:   * Filtrer une liste:
 +<code perl>
   @selection = grep { $_ > 10 } @liste;   @selection = grep { $_ > 10 } @liste;
 +</code>
   * Transformer les éléments d'une liste un par un:   * Transformer les éléments d'une liste un par un:
 +<code perl>
   @resultat = map { $_ * 2 } @liste;   @resultat = map { $_ * 2 } @liste;
 +</code>
  
 ===== Parcours ===== ===== Parcours =====
  
 Une des opérations les plus courantes en Perl consiste à parcourir les éléments d'une liste un par un. Il existe de nombreuses façons de le faire, dont les plus courantes sont : Une des opérations les plus courantes en Perl consiste à parcourir les éléments d'une liste un par un. Il existe de nombreuses façons de le faire, dont les plus courantes sont :
 +<code perl>
   foreach $mot (@hello) { print "$mot"; }   foreach $mot (@hello) { print "$mot"; }
   foreach (@hello) { print $_; }   foreach (@hello) { print $_; }
   foreach (@hello) { print; }   foreach (@hello) { print; }
   print foreach @hello;   print foreach @hello;
 +</code>
  
 Il est possible dans une structure de contrôle d'omettre le nom de l'itérateur (//$mot//), la variable //$_// est alors automatiquement utilisée. De même, la plupart des fonctions Perl vont spontanément utiliser cette variable comme argument si aucun ne lui est fourni (//print//). Il est possible dans une structure de contrôle d'omettre le nom de l'itérateur (//$mot//), la variable //$_// est alors automatiquement utilisée. De même, la plupart des fonctions Perl vont spontanément utiliser cette variable comme argument si aucun ne lui est fourni (//print//).
Ligne 164: Ligne 223:
  
 Exemple de déclaration et d'utilisation : Exemple de déclaration et d'utilisation :
-# Intialisation+<code perl> 
 +  # Intialisation
   my %menu = (   my %menu = (
   "entrée" => "salade",   "entrée" => "salade",
Ligne 171: Ligne 231:
   "prix" => 42   "prix" => 42
   );   );
- +   
-# Assignation+  # Assignation
   $menu{'prix'} = 45;   $menu{'prix'} = 45;
- +   
-# Lecture+  # Lecture
   print "Plat: ".$menu{'plat'};   print "Plat: ".$menu{'plat'};
 +</code>
  
 **Note**: on peut trouver des intialisations où le symbole **=>** est simplement une virgule, Perl pouvant effectivement considérer un tableau associatif sous sa forme "à plat", c'est-à-dire sous forme de liste de paires (clé, valeur) successives. **Note**: on peut trouver des intialisations où le symbole **=>** est simplement une virgule, Perl pouvant effectivement considérer un tableau associatif sous sa forme "à plat", c'est-à-dire sous forme de liste de paires (clé, valeur) successives.
Ligne 184: Ligne 244:
  
   * Obtenir la liste des clés (indices) :   * Obtenir la liste des clés (indices) :
 +<code perl>
   my @cle = keys %menu;   my @cle = keys %menu;
 +</code>
   * Vériier la présence d'une clé :   * Vériier la présence d'une clé :
 +<code perl>
   print "Le menu a un prix" if defined $menu{'prix'};   print "Le menu a un prix" if defined $menu{'prix'};
 +</code>
 +  * Ajouter un élément quelconque :
 +<code perl>
 +$menu($info) = "blablabla";
 +</code>
   * Retirer un élément quelconque :   * Retirer un élément quelconque :
 +<code perl>
   delete $menu{'prix'}; # Différent de $menu{'prix'} = undef; !   delete $menu{'prix'}; # Différent de $menu{'prix'} = undef; !
 +</code>
  
 ===== Parcours ===== ===== Parcours =====
  
 Les hashes Perl ne sont pas "ordonnés" (comme par exemple en PHP où l'ordre d'insertion est préservé), l'ordre de parcours des éléments n'est donc a priori pas défini - et en général différent à chaque parcours. Voici le parcours classique à l'aide de **each** : Les hashes Perl ne sont pas "ordonnés" (comme par exemple en PHP où l'ordre d'insertion est préservé), l'ordre de parcours des éléments n'est donc a priori pas défini - et en général différent à chaque parcours. Voici le parcours classique à l'aide de **each** :
 +<code perl>
   while (($cle, $val) = each %menu) {   while (($cle, $val) = each %menu) {
   print "$cle: $val\n";   print "$cle: $val\n";
   }   }
 +</code>
  
 On peut également extraire d'abord la liste de clés, et ainsi éventuellement effectuer un tri pour obtenir un parcours ordonné selon les clés : On peut également extraire d'abord la liste de clés, et ainsi éventuellement effectuer un tri pour obtenir un parcours ordonné selon les clés :
 +<code perl>
   print "$_: $menu{$_}\n" foreach (sort keys %menu); # Plus lisible que sort(keys(%menu))   print "$_: $menu{$_}\n" foreach (sort keys %menu); # Plus lisible que sort(keys(%menu))
 +</code>
 ====== 5. Contextes liste et scalaire ====== ====== 5. Contextes liste et scalaire ======
  
Ligne 205: Ligne 278:
  
 Par exemple, une liste évaluée dans un contexte scalaire renvoie le nombre de ses éléments. L'expression suivante vérifie donc bien que le nombre d'arguments fourni au programme est 2 (car d'une part, ====== est un opérateur arithmétique, d'autre part 2 est également un scalaire) : Par exemple, une liste évaluée dans un contexte scalaire renvoie le nombre de ses éléments. L'expression suivante vérifie donc bien que le nombre d'arguments fourni au programme est 2 (car d'une part, ====== est un opérateur arithmétique, d'autre part 2 est également un scalaire) :
 +<code perl>
   if (@ARGV ====== 2) ... # Le nombre d'arguments de @ARGV est considéré   if (@ARGV ====== 2) ... # Le nombre d'arguments de @ARGV est considéré
 +</code>
  
 On peut changer le contexte simplement en comparant avec une liste, et cette-fois ce sont bien les éléments de //@ARGV// qui seront pris en comptes : On peut changer le contexte simplement en comparant avec une liste, et cette-fois ce sont bien les éléments de //@ARGV// qui seront pris en comptes :
 +<code perl>
   if (@ARGV ====== ('--output', 'png')) ... # Le contenu de @ARGV est considéré   if (@ARGV ====== ('--output', 'png')) ... # Le contenu de @ARGV est considéré
 +</code>
  
 **Note 1**: //print// sait automatiquement afficher une liste, mais il le fait en concaténant les éléments. On peut utiliser //print join("\n", @liste)// pour afficher un élément par ligne (etc). **Note 1**: //print// sait automatiquement afficher une liste, mais il le fait en concaténant les éléments. On peut utiliser //print join("\n", @liste)// pour afficher un élément par ligne (etc).
Ligne 215: Ligne 292:
  
 Il existe d'autres contextes (comme celui du tableau associatif), mais ils sont utilisés de manière souvent moins transparente et sont clairement signalés. Il existe d'autres contextes (comme celui du tableau associatif), mais ils sont utilisés de manière souvent moins transparente et sont clairement signalés.
- 
perl/variables_et_structures_de_donnees.1237077621.txt.gz · Dernière modification : 2009/03/15 00:41 (modification externe)