Recherche…


Remarques

Les sous-routines obtiennent leurs arguments dans la variable magique appelée @_ . Bien qu'il ne soit pas nécessaire de le décompresser, il est recommandé, car il facilite la lecture et évite les modifications accidentelles, car les arguments de @_ sont transmis par référence (peuvent être modifiés).

Créer des sous-routines

Les sous-routines sont créées en utilisant le mot-clé sub suivi d'un identifiant et d'un bloc de code entre accolades.

Vous pouvez accéder aux arguments en utilisant la variable spéciale @_ , qui contient tous les arguments sous forme de tableau.

sub function_name {
    my ($arg1, $arg2, @more_args) = @_;
    # ...
}

Comme la fonction shift @_ défaut le décalage de @_ lorsqu'elle est utilisée dans un sous-programme, il est courant d'extraire les arguments séquentiellement dans des variables locales au début d'un sous-programme:

sub function_name {
    my $arg1 = shift;
    my $arg2 = shift;
    my @more_args = @_;
    # ...
}

# emulate named parameters (instead of positional)
sub function_name {
    my %args = (arg1 => 'default', @_);
    my $arg1 = delete $args{arg1};
    my $arg2 = delete $args{arg2};
    # ...
}

sub {
    my $arg1 = shift;
    # ...
}->($arg);
5.20.0

Alternativement, la caractéristique expérimentale "signatures" peut être utilisée pour décompresser les paramètres, qui sont passés par valeur ( pas par référence).

use feature "signatures";

sub function_name($arg1, $arg2, @more_args) {
    # ...
}

Les valeurs par défaut peuvent être utilisées pour les paramètres.

use feature "signatures";

sub function_name($arg1=1, $arg2=2) {
    # ...
}

Vous pouvez utiliser n'importe quelle expression pour donner une valeur par défaut à un paramètre, y compris d'autres paramètres.

sub function_name($arg1=1, $arg2=$arg1+1) {
    # ...
}

Notez que vous ne pouvez pas référencer les paramètres définis après le paramètre actuel. Le code suivant ne fonctionne donc pas comme prévu.

sub function_name($arg1=$arg2, $arg2=1) {
    print $arg1;  # => <nothing>
    print $arg2;  # => 1
}

Les arguments de sous-routine sont transmis par référence (sauf ceux des signatures)

Les arguments de sous-routine en Perl sont transmis par référence, sauf s'ils se trouvent dans la signature. Cela signifie que les membres du tableau @_ dans le sous-ensemble ne sont que des alias aux arguments réels. Dans l'exemple suivant, $text dans le programme principal reste modifié après l'appel du sous-programme car $_[0] à l'intérieur du sous-marin n'est en fait qu'un nom différent pour la même variable. La seconde invocation génère une erreur car un littéral de chaîne n'est pas une variable et ne peut donc pas être modifié.

use feature 'say';

sub edit {
    $_[0] =~ s/world/sub/;
}

my $text = "Hello, world!";
edit($text);
say $text;      # Hello, sub!

edit("Hello, world!"); # Error: Modification of a read-only value attempted

Pour éviter de frapper les variables de votre interlocuteur, il est donc important de copier @_ vers des variables localisées ( my ... ) comme décrit dans "Création de sous-routines".

Sous-routines

Les sous-programmes contiennent du code. Sauf indication contraire, ils sont définis globalement.

# Functions do not (have to) specify their argument list
sub returns_one {
  # Functions return the value of the last expression by default
  # The return keyword here is unnecessary, but helps readability.
  return 1;
}

# Its arguments are available in @_, however
sub sum {
  my $ret = 0;
  for my $value (@_) {
    $ret += $value
  }
  return $ret;
}

# Perl makes an effort to make parens around argument list optional
say sum 1..3;     # 6

# If you treat functions as variables, the & sigil is mandatory.
say defined &sum; # 1

Certains builtins tels que l' print ou say sont des mots clés, pas les fonctions, donc par exemple &say est indéfini. Cela signifie également que vous pouvez les définir, mais vous devrez spécifier le nom du paquet pour les appeler réellement

# This defines the function under the default package, 'main'
sub say {
  # This is instead the say keyword
  say "I say, @_";
}

# ...so you can call it like this: 
main::say('wow'); # I say, wow.
5.18.0

Depuis Perl 5.18, vous pouvez également avoir des fonctions non globales:

use feature 'lexical_subs';
my $value;
{
  # Nasty code ahead
  my sub prod {
    my $ret = 1;
    $ret *= $_ for @_;
    $ret;
  }
  $value = prod 1..6; # 720 
  say defined &prod; # 1
}
say defined &prod; # 0
5.20.0

Depuis 5.20, vous pouvez également avoir des paramètres nommés.

use feature 'signatures';
sub greet($name) {
  say "Hello, $name";
}

Cela ne doit pas être confondu avec les prototypes, une installation que Perl doit vous permettre de définir des fonctions qui se comportent comme des éléments intégrés. Les prototypes de fonctions doivent être visibles au moment de la compilation et ses effets peuvent être ignorés en spécifiant le & sigil. Les prototypes sont généralement considérés comme une fonctionnalité avancée qui est mieux utilisée avec précaution.

# This prototype makes it a compilation error to call this function with anything 
# that isn't an array. Additionally, arrays are automatically turned into arrayrefs
sub receives_arrayrefs(\@\@) {
   my $x = shift;
   my $y = shift;
}

my @a = (1..3);
my @b = (1..4);
receives_arrayrefs(@a, @b);    # okay,   $x = \@a, $y = \@b, @_ = ();
receives_arrayrefs(\@a, \@b);  # compilation error, "Type … must be array …"
BEGIN { receives_arrayrefs(\@a, \@b); }

# Specify the sigil to ignore the prototypes. 
&receives_arrayrefs(\@a, \@b); # okay,   $x = \@a, $y = \@b, @_ = ();
&receives_arrayrefs(@a, @b);   # ok, but $x = 1,   $y = 2,   @_ = (3,1,2,3,4);


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