Perl - Sous-routines
Un sous-programme ou une fonction Perl est un groupe d'instructions qui exécutent ensemble une tâche. Vous pouvez diviser votre code en sous-programmes distincts. La façon dont vous divisez votre code entre différents sous-programmes dépend de vous, mais logiquement, la division est généralement faite pour que chaque fonction effectue une tâche spécifique.
Perl utilise les termes sous-programme, méthode et fonction de manière interchangeable.
Définir et appeler un sous-programme
La forme générale d'une définition de sous-programme dans le langage de programmation Perl est la suivante:
sub subroutine_name {
body of the subroutine
}
La manière typique d'appeler ce sous-programme Perl est la suivante:
subroutine_name( list of arguments );
Dans les versions de Perl antérieures à 5.0, la syntaxe pour appeler les sous-programmes était légèrement différente, comme indiqué ci-dessous. Cela fonctionne toujours dans les dernières versions de Perl, mais ce n'est pas recommandé car il contourne les prototypes de sous-programmes.
&subroutine_name( list of arguments );
Jetons un œil à l'exemple suivant, qui définit une fonction simple, puis appelons-la. Parce que Perl compile votre programme avant de l'exécuter, peu importe où vous déclarez votre sous-programme.
#!/usr/bin/perl
# Function definition
sub Hello {
print "Hello, World!\n";
}
# Function call
Hello();
Lorsque le programme ci-dessus est exécuté, il produit le résultat suivant -
Hello, World!
Passer des arguments à un sous-programme
Vous pouvez passer divers arguments à un sous-programme comme vous le faites dans n'importe quel autre langage de programmation et ils peuvent être accédés à l'intérieur de la fonction en utilisant le tableau spécial @_. Ainsi, le premier argument de la fonction est dans $ _ [0], le second dans $ _ [1], et ainsi de suite.
Vous pouvez passer des tableaux et des hachages en tant qu'arguments comme n'importe quel scalaire, mais en passant plus d'un tableau ou hachage, ils perdent normalement leurs identités distinctes. Nous utiliserons donc des références (expliquées dans le chapitre suivant) pour passer n'importe quel tableau ou hachage.
Essayons l'exemple suivant, qui prend une liste de nombres puis imprime leur moyenne -
#!/usr/bin/perl
# Function definition
sub Average {
# get total number of arguments passed.
$n = scalar(@_);
$sum = 0;
foreach $item (@_) {
$sum += $item;
}
$average = $sum / $n;
print "Average for the given numbers : $average\n";
}
# Function call
Average(10, 20, 30);
Lorsque le programme ci-dessus est exécuté, il produit le résultat suivant -
Average for the given numbers : 20
Passer des listes aux sous-programmes
Comme la variable @_ est un tableau, elle peut être utilisée pour fournir des listes à un sous-programme. Cependant, en raison de la manière dont Perl accepte et analyse les listes et les tableaux, il peut être difficile d'extraire les éléments individuels de @_. Si vous devez passer une liste avec d'autres arguments scalaires, créez une liste comme dernier argument comme indiqué ci-dessous -
#!/usr/bin/perl
# Function definition
sub PrintList {
my @list = @_;
print "Given list is @list\n";
}
$a = 10;
@b = (1, 2, 3, 4);
# Function call with list parameter
PrintList($a, @b);
Lorsque le programme ci-dessus est exécuté, il produit le résultat suivant -
Given list is 10 1 2 3 4
Passer des hachages aux sous-programmes
Lorsque vous fournissez un hachage à un sous-programme ou à un opérateur qui accepte une liste, le hachage est automatiquement traduit en une liste de paires clé / valeur. Par exemple -
#!/usr/bin/perl
# Function definition
sub PrintHash {
my (%hash) = @_;
foreach my $key ( keys %hash ) {
my $value = $hash{$key};
print "$key : $value\n";
}
}
%hash = ('name' => 'Tom', 'age' => 19);
# Function call with hash parameter
PrintHash(%hash);
Lorsque le programme ci-dessus est exécuté, il produit le résultat suivant -
name : Tom
age : 19
Valeur renvoyée à partir d'un sous-programme
Vous pouvez renvoyer une valeur à partir d'un sous-programme comme vous le faites dans n'importe quel autre langage de programmation. Si vous ne renvoyez pas de valeur à partir d'un sous-programme, le dernier calcul effectué dans un sous-programme est également automatiquement la valeur de retour.
Vous pouvez renvoyer des tableaux et des hachages à partir du sous-programme comme n'importe quel scalaire, mais le renvoi de plusieurs tableaux ou hachages les fait normalement perdre leurs identités distinctes. Nous utiliserons donc des références (expliquées dans le chapitre suivant) pour renvoyer n'importe quel tableau ou hachage d'une fonction.
Essayons l'exemple suivant, qui prend une liste de nombres puis renvoie leur moyenne -
#!/usr/bin/perl
# Function definition
sub Average {
# get total number of arguments passed.
$n = scalar(@_);
$sum = 0;
foreach $item (@_) {
$sum += $item;
}
$average = $sum / $n;
return $average;
}
# Function call
$num = Average(10, 20, 30);
print "Average for the given numbers : $num\n";
Lorsque le programme ci-dessus est exécuté, il produit le résultat suivant -
Average for the given numbers : 20
Variables privées dans un sous-programme
Par défaut, toutes les variables en Perl sont des variables globales, ce qui signifie qu'elles sont accessibles de n'importe où dans le programme. Mais tu peux créerprivate variables appelées lexical variables à tout moment avec le my opérateur.
le myL'opérateur limite une variable à une région de code particulière dans laquelle elle peut être utilisée et accessible. En dehors de cette région, cette variable ne peut pas être utilisée ou accessible. Cette région s'appelle sa portée. Une portée lexicale est généralement un bloc de code entouré d'un ensemble d'accolades, telles que celles définissant le corps du sous-programme ou celles marquant les blocs de code des instructions if, while, for, foreach et eval .
Voici un exemple vous montrant comment définir une ou plusieurs variables privées à l'aide de my opérateur -
sub somefunc {
my $variable; # $variable is invisible outside somefunc()
my ($another, @an_array, %a_hash); # declaring many variables at once
}
Vérifions l'exemple suivant pour faire la distinction entre les variables globales et privées -
#!/usr/bin/perl
# Global variable
$string = "Hello, World!";
# Function definition
sub PrintHello {
# Private variable for PrintHello function
my $string;
$string = "Hello, Perl!";
print "Inside the function $string\n";
}
# Function call
PrintHello();
print "Outside the function $string\n";
Lorsque le programme ci-dessus est exécuté, il produit le résultat suivant -
Inside the function Hello, Perl!
Outside the function Hello, World!
Valeurs temporaires via local ()
le localest principalement utilisé lorsque la valeur actuelle d'une variable doit être visible par les sous-programmes appelés. Un local donne juste des valeurs temporaires aux variables globales (c'est-à-dire package). C'est ce qu'on appelle la portée dynamique . La portée lexicale est effectuée avec my, qui fonctionne plus comme les déclarations automatiques de C.
Si plus d'une variable ou expression est donnée à local, elles doivent être placées entre parenthèses. Cet opérateur fonctionne en sauvegardant les valeurs actuelles de ces variables dans sa liste d'arguments sur une pile cachée et en les restaurant à la sortie du bloc, du sous-programme ou de l'évaluation.
Vérifions l'exemple suivant pour faire la distinction entre les variables globales et locales -
#!/usr/bin/perl
# Global variable
$string = "Hello, World!";
sub PrintHello {
# Private variable for PrintHello function
local $string;
$string = "Hello, Perl!";
PrintMe();
print "Inside the function PrintHello $string\n";
}
sub PrintMe {
print "Inside the function PrintMe $string\n";
}
# Function call
PrintHello();
print "Outside the function $string\n";
Lorsque le programme ci-dessus est exécuté, il produit le résultat suivant -
Inside the function PrintMe Hello, Perl!
Inside the function PrintHello Hello, Perl!
Outside the function Hello, World!
Variables d'état via state ()
Il existe un autre type de variables lexicales, qui sont similaires aux variables privées mais qui conservent leur état et ne sont pas réinitialisées lors de plusieurs appels des sous-programmes. Ces variables sont définies à l'aide dustate opérateur et disponible à partir de Perl 5.9.4.
Vérifions l'exemple suivant pour démontrer l'utilisation de state variables -
#!/usr/bin/perl
use feature 'state';
sub PrintCount {
state $count = 0; # initial value
print "Value of counter is $count\n";
$count++;
}
for (1..5) {
PrintCount();
}
Lorsque le programme ci-dessus est exécuté, il produit le résultat suivant -
Value of counter is 0
Value of counter is 1
Value of counter is 2
Value of counter is 3
Value of counter is 4
Avant Perl 5.10, vous deviez l'écrire comme ceci -
#!/usr/bin/perl
{
my $count = 0; # initial value
sub PrintCount {
print "Value of counter is $count\n";
$count++;
}
}
for (1..5) {
PrintCount();
}
Contexte d'appel de sous-programme
Le contexte d'un sous-programme ou d'une instruction est défini comme le type de valeur de retour attendu. Cela vous permet d'utiliser une seule fonction qui renvoie différentes valeurs en fonction de ce que l'utilisateur attend de recevoir. Par exemple, le localtime () suivant renvoie une chaîne lorsqu'il est appelé dans un contexte scalaire, mais il renvoie une liste lorsqu'il est appelé dans un contexte de liste.
my $datestring = localtime( time );
Dans cet exemple, la valeur de $ timestr est désormais une chaîne composée de la date et de l'heure actuelles, par exemple, Thu Nov 30 15:21:33 2000. Inversement -
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
Désormais, les variables individuelles contiennent les valeurs correspondantes renvoyées par le sous-programme localtime ().