Recherche…


Syntaxe

  • ma déclaration # lexicale
  • notre # Déclaration globale
  • $ foo # Scalar
  • @foo # Array
  • $ # foo # Array Last-Index
  • % foo # Hash
  • $ {$ foo} # Dé-référence scalaire
  • @ {$ foo} # Array De-Reference
  • $ # {$ foo} # Array-DeRef Dernier index
  • % {$ foo} # Hash De-Reference
  • $ foo [$ index] # Array est indexé
  • $ {$ foo} [$ index] # Array De-Reference et obtenir indexés.
  • $ foo -> [$ index] # Array De-Reference et obtenir indexé (simplifié)
  • $ foo {$ key} # Hash obtient la valeur de la clé
  • $ {$ foo} {$ key} # Hash Dereference et récupère la valeur de la clé
  • $ foo -> {$ key} # Hash Dereference et obtenir la valeur de la clé (simplifié)
  • \ $ x # Référence à Scalar
  • \ @x # Référence à un tableau
  • \% x # Référence au hachage
  • = [] # Référence à un tableau anonyme (Inline)
  • = {} # Référence au hachage anonyme (Inline)

Scalaires

Les scalaires sont le type de données le plus élémentaire de Perl. Ils sont marqués avec le sigil $ et contiennent une seule valeur de l'un des trois types:

  • un numéro ( 3 , 42 , 3.141 , etc.)
  • une chaîne ( 'hi' , "abc" , etc.)
  • une référence à une variable (voir d'autres exemples).
my $integer = 3;                      # number
my $string = "Hello World";           # string
my $reference = \$string;             # reference to $string

Perl convertit à la volée les nombres et les chaînes en fonction des attentes d’un opérateur.

my $number = '41';                    # string '41'
my $meaning = $number + 1;            # number  42
my $sadness = '20 apples';            # string '20 apples'
my $danger = $sadness * 2;            # number '40', raises warning

Lors de la conversion d'une chaîne en nombre, Perl prend autant de chiffres que possible sur le recto d'une chaîne - d'où pourquoi 20 apples sont converties en 20 dans la dernière ligne.

Selon que vous souhaitez traiter le contenu d'un scalaire sous forme de chaîne ou de nombre, vous devez utiliser différents opérateurs. Ne pas les mélanger

# String comparison                   # Number comparison
'Potato' eq 'Potato';                 42 == 42;
'Potato' ne 'Pomato';                 42 != 24;
'Camel'  lt 'Potato';                 41 < 42;
'Zombie' gt 'Potato';                 43 > 42;

# String concatenation                # Number summation
'Banana' . 'phone';                   23 + 19;

# String repetition                   # Number multiplication 
'nan' x 3;                            6 * 7;

Tenter d'utiliser des opérations de chaîne sur des nombres ne déclenchera pas d'avertissement; tenter d'utiliser des opérations numériques sur des chaînes non numériques sera. Sachez que certaines chaînes non numériques telles que 'inf' , 'nan' , '0 but true' comptent comme des nombres.

Tableaux

Les tableaux stockent une séquence ordonnée de valeurs. Vous pouvez accéder au contenu par index ou les parcourir. Les valeurs resteront dans l'ordre dans lequel vous les avez remplies.

my @numbers_to_ten = (1,2,3,4,5,6,7,8,9,10); # More conveniently: (1..10)
my @chars_of_hello = ('h','e','l','l','o');
my @word_list = ('Hello','World');

# Note the sigil: access an @array item with $array[index]
my $second_char_of_hello = $chars_of_hello[1]; # 'e'

# Use negative indices to count from the end (with -1 being last)
my $last_char_of_hello = $chars_of_hello[-1];

# Assign an array to a scalar to get the length of the array
my $length_of_array = @chars_of_hello; # 5

# You can use $# to get the last index of an array, and confuse Stack Overflow
my $last_index_of_array = $#chars_of_hello; # 4

# You can also access multiple elements of an array at the same time
# This is called "array slice"
# Since this returns multiple values, the sigil to use here on the RHS is @
my @some_chars_of_hello = @chars_of_hello[1..3]; # ('H', 'e', 'l')
my @out_of_order_chars = @chars_of_hello[1,4,2]; # ('e', 'o', 'l')

# In Python you can say array[1:-1] to get all elements but first and last
# Not so in Perl: (1..-1) is an empty list. Use $# instead
my @empty_list = @chars_of_hello[1..-1];                           # ()
my @inner_chars_of_hello = @chars_of_hello[1..$#chars_of_hello-1]; # ('e','l','l')

# Access beyond the end of the array yields undef, not an error
my $undef = $chars_of_hello[6]; # undef    

Les tableaux sont mutables:

use utf8; # necessary because this snippet is utf-8
$chars_of_hello[1] = 'u';              #     ('h','u','l','l','o')
push @chars_of_hello, ('!', '!');      #     ('h','u','l','l','o','!','!')
pop @chars_of_hello;                   #     ('h','u','l','l','o','!')
shift @chars_of_hello;                 #         ('u','l','l','o','!')
unshift @chars_of_hello, ('¡', 'H');   # ('¡','H','u','l','l','o','!')
@chars_of_hello[2..5] = ('O','L','A'); # ('¡','H','O','L','A',undef,'!') whoops! 
delete $chars_of_hello[-2];            # ('¡','H','O','L','A',      '!')

# Setting elements beyond the end of an array does not result in an error
# The array is extended with undef's as necessary. This is "autovivification."
my @array;           # ()
my @array[3] = 'x';  # (undef, undef, undef, 'x')

Enfin, vous pouvez parcourir le contenu d'un tableau:

use v5.10; # necessary for 'say'
for my $number (@numbers_to_ten) {
  say $number ** 2;
}

Lorsqu'ils sont utilisés comme booléens, les tableaux sont vrais s'ils ne sont pas vides.

Hash

Les hachages peuvent être compris comme des tables de correspondance. Vous pouvez accéder à son contenu en spécifiant une clé pour chacun d'entre eux. Les clés doivent être des chaînes. Si ce n'est pas le cas, ils seront convertis en chaînes.

Si vous donnez simplement au hash une clé connue, cela vous servira sa valeur.

# Elements are in (key, value, key, value) sequence
my %inhabitants_of = ("London", 8674000, "Paris", 2244000);

# You can save some typing and gain in clarity by using the "fat comma"
# syntactical sugar. It behaves like a comma and quotes what's on the left.
my %translations_of_hello = (spanish => 'Hola', german => 'Hallo', swedish => 'Hej'); 

Dans l'exemple suivant, notez les crochets et sigil: vous accédez à un élément de %hash utilisant $hash{key} car la valeur que vous voulez est un scalaire. Certains considèrent qu'il est recommandé de citer la clé alors que d'autres trouvent ce style visuellement bruyant. La citation n'est requise que pour les clés qui pourraient être confondues avec des expressions telles que $hash{'some-key'}

my $greeting = $translations_of_hello{'spanish'};

Alors que Perl essaiera par défaut d'utiliser des mots nus comme des chaînes, + modificateur peut également être utilisé pour indiquer à Perl que la clé ne doit pas être interpolée mais exécutée avec le résultat de l'exécution utilisé comme clé:

my %employee = ( name => 'John Doe', shift => 'night' );
# this example will print 'night'
print $employee{shift}; 

# but this one will execute [shift][1], extracting first element from @_,
# and use result as a key
print $employee{+shift};

Comme avec les tableaux, vous pouvez accéder à plusieurs éléments de hachage en même temps. Ceci est appelé une tranche de hachage . La valeur résultante est une liste, utilisez donc le sigil @ :

my @words = @translations_of_hello{'spanish', 'german'}; # ('Hola', 'Hallo')

Itérer sur les clés d'un hachage avec les keys keys renverra les éléments dans un ordre aléatoire. Combinez avec le sort si vous le souhaitez.

for my $lang (sort keys %translations_of_hello) {
  say $translations_of_hello{$lang};
}

Si vous n'avez pas besoin des clés comme dans l'exemple précédent, values renvoie directement les valeurs de hachage:

for my $translation (values %translations_of_hello) {
  say $translation;
}

Vous pouvez également utiliser une boucle while avec each pour parcourir le hachage. De cette façon, vous obtiendrez à la fois la clé et la valeur, sans recherche de valeur séparée. Son utilisation est cependant déconseillée, each pouvant se briser de manière floue.

# DISCOURAGED
while (my ($lang, $translation) = each %translations_of_hello) {
  say $translation;
}

L'accès aux éléments non définis renvoie undef, pas une erreur:

my $italian = $translations_of_hello{'italian'}; # undef

map aplatissement des map et des listes peut être utilisé pour créer des hachages à partir de tableaux. C'est un moyen populaire de créer un ensemble de valeurs, par exemple pour vérifier rapidement si une valeur est dans @elems . Cette opération prend généralement O (n) time (c'est-à-dire proportionnelle au nombre d'éléments) mais peut être effectuée à temps constant (O (1)) en transformant la liste en hash:

@elems = qw(x y x z t);
my %set = map { $_ => 1 } @elems;   # (x, 1, y, 1, t, 1)
my $y_membership = $set{'y'};       # 1
my $w_membership = $set{'w'};       # undef

Cela nécessite des explications. Le contenu de @elems est lu dans une liste qui est traitée par map . map accepte un bloc de code appelé pour chaque valeur de sa liste d'entrée; la valeur de l'élément est disponible pour utilisation dans $_ . Notre bloc de code renvoie deux éléments de liste pour chaque élément d'entrée: $_ , l'élément d'entrée et 1 , juste une valeur. Une fois que vous avez comptabilisé l'aplatissement des listes, le résultat est que la map { $_ => 1 } @elems transforme qw(xyxzt) en (x => 1, y => 1, x => 1, z => 1, t => 1) .

Lorsque ces éléments sont affectés au hachage, les éléments impairs deviennent des clés de hachage et même les éléments deviennent des valeurs de hachage. Lorsqu'une clé est spécifiée plusieurs fois dans une liste pour être affectée à un hachage, la dernière valeur gagne. Cela élimine efficacement les doublons.

Un moyen plus rapide de transformer une liste en une table de hachage utilise l'affectation à une tranche de hachage. Il utilise l'opérateur x pour multiplier la liste à un seul élément (1) par la taille de @elems , il y a donc une valeur 1 pour chacune des clés de la tranche à gauche:

@elems = qw(x y x z t);
my %set;
@set{@elems} = (1) x @elems;

L'application de hachage suivante exploite également le fait que les hachages et les listes peuvent souvent être utilisés indifféremment pour implémenter des arguments de fonction nommés:

sub hash_args {
  my %args = @_;
  my %defaults = (foo => 1, bar => 0);
  my %overrides = (__unsafe => 0);
  my %settings = (%defaults, %args, %overrides);
}

# This function can then be called like this:
hash_args(foo => 5, bar => 3); # (foo => 5, bar => 3, __unsafe ==> 0)
hash_args();                   # (foo => 1, bar => 0, __unsafe ==> 0)
hash_args(__unsafe => 1)       # (foo => 1, bar => 0, __unsafe ==> 0)

Lorsqu'ils sont utilisés comme des booléens, les hachages sont vrais s'ils ne sont pas vides.

Références scalaires

Une référence est une variable scalaire (une préfixée par $ ) qui «renvoie» à d'autres données.

my $value     = "Hello";
my $reference = \$value;
print $value;     # => Hello
print $reference; # => SCALAR(0x2683310)

Pour obtenir les données référencées , vous les référencez .

say ${$reference};                  # Explicit prefix syntax
say $$reference;                    # The braces can be left out (confusing)
5.24.0

Nouvelle syntaxe de déréférencement postfix, disponible par défaut à partir de la v5.24

use v5.24;
say $reference->$*; # New postfix notation

Cette "valeur dé-référencée" peut alors être modifiée comme si c'était la variable d'origine.

${$reference} =~ s/Hello/World/;
print ${$reference};  # => World
print $value;         # => World

Une référence est toujours véridique - même si la valeur à laquelle elle fait référence est falsifiée (comme 0 ou "" ).

Vous voudrez peut-être une référence scalaire si:

  • Vous voulez passer une chaîne à une fonction et la modifier pour vous sans qu'il s'agisse d'une valeur de retour.

  • Vous souhaitez éviter explicitement que Perl copie implicitement le contenu d'une chaîne de caractères volumineuse à un moment donné de votre fonction (particulièrement sur les versions antérieures de Perls sans les chaînes de copie).

  • Vous souhaitez désambiguïser des valeurs de type chaîne avec une signification spécifique, à partir de chaînes qui véhiculent du contenu, par exemple:

    • Désambiguïser un nom de fichier du contenu du fichier
    • Désambiguïser le contenu renvoyé à partir d'une chaîne d'erreur renvoyée
  • Vous souhaitez implémenter un modèle d'objet fin et léger, dans lequel les objets transmis au code d'appel ne comportent pas de métadonnées visibles par l'utilisateur:

    our %objects;
    my $next_id = 0;
    sub new { 
       my $object_id = $next_id++;
       $objects{ $object_id } = { ... }; # Assign data for object
       my $ref = \$object_id;
       return bless( $ref, "MyClass" );
    }
    

Références de tableau

Les références de tableaux sont des scalaires ( $ ) qui font référence à des tableaux.

my @array = ("Hello"); # Creating array, assigning value from a list
my $array_reference = \@array;

Ceux-ci peuvent être créés plus court comme suit:

my $other_array_reference = ["Hello"];

La modification / utilisation de références de tableau nécessite leur suppression.

my @contents = @{ $array_reference };               # Prefix notation
my @contents = @$array_reference;                   # Braces can be left out
5.24.0

Nouvelle syntaxe de déréférencement postfix, disponible par défaut à partir de la v5.24

use v5.24;
my @contents = $array_reference->@*; # New postfix notation 

Lorsque vous accédez au contenu d'une table RAF par index, vous pouvez utiliser le sucre syntaxique -> .

my @array = qw(one two three);      my $arrayref = [ qw(one two three) ]
my $one = $array[0];                my $one = $arrayref->[0];

Contrairement aux tableaux, les tableaux peuvent être imbriqués:

my @array = ( (1, 0), (0, 1) )  # ONE array of FOUR elements: (1, 0, 0, 1)
my @matrix = ( [1, 0], [0, 1] ) # an array of two arrayrefs
my $matrix = [ [0, 1], [1, 0] ] # an arrayref of arrayrefs
# There is no namespace conflict between scalars, arrays and hashes
# so @matrix and $matrix _both_ exist at this point and hold different values.

my @diagonal_1 = ($matrix[0]->[1], $matrix[1]->[0])     # uses @matrix
my @diagonal_2 = ($matrix->[0]->[1], $matrix->[1]->[0]) # uses $matrix
# Since chained []- and {}-access can only happen on references, you can
# omit some of those arrows.
my $corner_1 = $matrix[0][1];   # uses @matrix;
my $corner_2 = $matrix->[0][1]; # uses $matrix;  

Lorsqu'elles sont utilisées comme booléennes, les références sont toujours vraies.

Références de hachage

Les références de hachage sont des scalaires qui contiennent un pointeur sur l'emplacement de la mémoire contenant les données d'un hachage. Étant donné que le scalaire pointe directement sur le hachage lui-même, lorsqu'il est transmis à un sous-programme, les modifications apportées au hachage ne sont pas locales au sous-programme comme avec un hachage normal, mais sont globales.

Tout d'abord, examinons ce qui se passe lorsque vous passez un hachage normal à un sous-programme et que vous le modifiez ici:

use strict;
use warnings;
use Data::Dumper;

sub modify
{
    my %hash = @_;

    $hash{new_value} = 2;

    print Dumper("Within the subroutine");
    print Dumper(\%hash);

    return;
}

my %example_hash = (
    old_value   => 1,
);

modify(%example_hash);

print Dumper("After exiting the subroutine");
print Dumper(\%example_hash);

Qui aboutit à:

$VAR1 = 'Within the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
          'old_value' => 1
        };

Notez qu'après avoir quitté le sous-programme, le hachage reste inchangé; toutes les modifications apportées étaient locales au sous-programme de modification, car nous avons transmis une copie du hachage, et non le hachage lui-même.

En comparaison, lorsque vous transmettez un hashref, vous transmettez l'adresse au hachage d'origine, de sorte que toute modification apportée dans le sous-programme sera effectuée sur le hachage d'origine:

use strict;
use warnings;
use Data::Dumper;

sub modify
{
    my $hashref = shift;

    # De-reference the hash to add a new value
    $hashref->{new_value} = 2;

    print Dumper("Within the subroutine");
    print Dumper($hashref);

    return;
}

# Create a hashref
my $example_ref = {
    old_value   => 1,
};

# Pass a hashref to a subroutine
modify($example_ref);

print Dumper("After exiting the subroutine");
print Dumper($example_ref);

Cela se traduira par:

$VAR1 = 'Within the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };
$VAR1 = 'After exiting the subroutine';
$VAR1 = {
          'new_value' => 2,
          'old_value' => 1
        };

Typeglobs, réfs de typeglob, descripteurs de fichiers et constantes

Un typeglob *foo contient des références au contenu des variables globales portant ce nom: $foo , @foo , $foo , &foo , etc. Vous pouvez y accéder comme un hachage et affecter directement les tables de symboles (evil!).

use v5.10; # necessary for say
our $foo = "foo";
our $bar;
say ref *foo{SCALAR};     # SCALAR
say ${ *foo{SCALAR} };    # bar
*bar = *foo;
say $bar;                 # bar
$bar = 'egg';
say $foo;                 # egg

Les typesglobs sont plus couramment utilisés pour traiter les fichiers. open , par exemple, crée une référence à un typeglob lorsqu'on lui demande de créer un descripteur de fichier non global:

use v5.10; # necessary for say
open(my $log, '> utf-8', '/tmp/log') or die $!; # open for writing with encoding
say $log 'Log opened';

# You can dereference this globref, but it's not very useful.
say ref $log;                   # GLOB
say (*{$log}->{IO} // 'undef'); # undef

close $log or die $!;

Typeglobs peut également être utilisé pour créer des variables en lecture seule globales, bien que l' use constant soit plus répandue.

# Global constant creation
*TRUE = \('1');
our $TRUE;
say $TRUE;  # 1
$TRUE = ''; # dies, "Modification of a read-only value attempted"

# use constant instead defines a parameterless function, therefore it's not global,
# can be used without sigils, can be imported, but does not interpolate easily.
use constant (FALSE => 0);
say FALSE;        # 0
say &FALSE;       # 0
say "${\FALSE}";  # 0 (ugh)
say *FALSE{CODE}; # CODE(0xMA1DBABE)

# Of course, neither is truly constant when you can manipulate the symbol table...
*TRUE = \('');
use constant (EVIL => 1);
*FALSE = *EVIL;

Sigils

Perl a plusieurs sigils:

$scalar = 1; # individual value
@array = ( 1, 2, 3, 4, 5 ); # sequence of values
%hash = ('it', 'ciao', 'en', 'hello', 'fr', 'salut'); # unordered key-value pairs
&function('arguments'); # subroutine
*typeglob; # symbol table entry

Celles-ci ressemblent à des sceaux, mais ne sont pas:

\@array; # \ returns the reference of what's on the right (so, a reference to @array)
$#array; # this is the index of the last element of @array

Vous pouvez utiliser des accolades après le sigil si vous le souhaitez. Cela améliore parfois la lisibilité.

say ${value} = 5;

Bien que vous utilisiez des sigils différents pour définir des variables de différents types, la même variable est accessible de différentes manières en fonction des sigils que vous utilisez.

%hash;            # we use % because we are looking at an entire hash
$hash{it};        # we want a single value, however, that's singular, so we use $
$array[0];        # likewise for an array. notice the change in brackets.
@array[0,3];      # we want multiple values of an array, so we instead use @
@hash{'it','en'}; # similarly for hashes (this gives the values: 'ciao', 'hello')
%hash{'it','fr'}; # we want an hash with just some of the keys, so we use %
                  # (this gives key-value pairs: 'it', 'ciao', 'fr', 'salut')

Ceci est particulièrement vrai pour les références. Pour utiliser une valeur référencée, vous pouvez combiner des sigils ensemble.

my @array = 1..5;                    # This is an array
my $reference_to_an_array = \@array; # A reference to an array is a singular value
push @array, 6;                      # push expects an array
push @$reference_to_an_array, 7;     # the @ sigil means what's on the right is an array
                                     # and what's on the right is $reference_to_an_array
                                     # hence: first a @, then a $

Voici une façon peut-être moins déroutante d'y penser. Comme nous l'avons vu précédemment, vous pouvez utiliser des accolades pour envelopper ce qui se trouve à droite d'un sceau. Vous pouvez donc penser à @{} comme quelque chose qui prend une référence de tableau et vous donne le tableau référencé.

# pop does not like array references
pop $reference_to_an_array; # ERROR in Perl 5.20+
# but if we use @{}, then...
pop @{ $reference_to_an_array }; # this works!

En fait, @{} accepte en réalité une expression:

my $values = undef;
say pop @{ $values };       # ERROR: can't use undef as an array reference
say pop @{ $values // [5] } # undef // [5] gives [5], so this prints 5

... et le même truc fonctionne aussi pour les autres sceaux.

# This is not an example of good Perl. It is merely a demonstration of this language feature
my $hashref = undef;
for my $key ( %{ $hashref // {} } ) {
  "This doesn't crash";
}

... mais si "l'argument" d'un sceau est simple, vous pouvez laisser les accolades.

say $$scalar_reference;
say pop @$array_reference;
for keys (%$hash_reference) { ... };

Les choses peuvent devenir excessivement extravagantes. Cela fonctionne, mais s'il vous plaît Perl responsable.

my %hash = (it => 'ciao', en => 'hi', fr => 'salut');
my $reference = \%hash;
my $reference_to_a_reference = \$reference;

my $italian = $hash{it};                              # Direct access 
my @greets = @$reference{'it', 'en'};                 # Dereference, then access as array
my %subhash = %$$reference_to_a_reference{'en', 'fr'} # Dereference ×2 then access as hash

Pour une utilisation normale, vous pouvez simplement utiliser des noms de sous-programmes sans sigil. (Variables sans Sigil sont généralement appelés « barewords ».) Le & Sigil est utile que dans un nombre limité de cas.

  • Faire une référence à une sous-routine:

    sub many_bars { 'bar' x $_[0] }
    my $reference = \&many_bars;
    say $reference->(3); # barbarbar
    
  • Appel d'une fonction en ignorant son prototype.

  • Combiné avec goto, comme un appel de fonction légèrement étrange dont la trame d'appel en cours est remplacée par l'appelant. Pensez à l'appel API linux exec() , mais pour les fonctions.



Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow