Le traitement des arguments de ligne de commande est une tâche fondamentale pour les programmes Perl. Historiquement, Perl a fourni la variable @ARGV pour accéder aux arguments passés au script. Le problème est que des scénarios complexes peuvent inclure des drapeaux et des paramètres clé-valeur, ce qui nécessite un parsing manuel du tableau @ARGV. Avec une approche incorrecte, il est possible de mal traiter les paramètres, de passer des valeurs obligatoires ou de traiter des valeurs superflues, ce qui mène à des erreurs dans la logique du programme.
La solution consiste à utiliser un traitement systématique : itération sur @ARGV, analyse du contenu, traitement des clés et de leurs valeurs.
Exemple de code :
my %args; while (my $arg = shift @ARGV) { if ($arg =~ /^--(\w+)=?(.*)/) { my ($key, $val) = ($1, $2); if ($val eq '' && @ARGV) { $val = shift @ARGV; # valeur suivante } $args{$key} = $val eq '' ? 1 : $val; } else { push @{$args{'_free'}}, $arg; } } print "Got foo: $args{foo} " if exists $args{foo};
Caractéristiques clés :
Que se passe-t-il si l'argument est transmis sous la forme '--flag value' au lieu de '--flag=value' ?
Si on ne traite que la séparation par '=', la valeur sera une chaîne vide, et le prochain élément du tableau sera ignoré comme un argument autonome. La solution consiste à tenir compte des deux variantes lors de l'analyse :
if ($arg =~ /^--(\w+)=?(.*)/)
et si $val est vide, prendre l'élément suivant.
Comment Perl se comporte-t-il avec des arguments contenant des espaces ?
Perl ne sépare pas les arguments à l'intérieur de @ARGV par des espaces, toute la division est effectuée par le shell. Ainsi, "--foo=bar baz" sera pris comme deux éléments différents, à moins que la chaîne ne soit mise entre guillemets dans la ligne de commande. Cela doit être pris en compte et il convient toujours d'exiger de l'utilisateur qu'il échappe aux espaces.
Est-il possible de modifier @ARGV avec shift, sans perdre les arguments d'origine ?
Shift modifie le tableau lui-même, la liste originale des arguments ne peut pas être récupérée. Si vous devez conserver le contenu d'origine de @ARGV, vous devez le cloner au préalable :
my @original_argv = @ARGV;
Le script ne traitait que les clés de type '--foo=bar', ignorant '--foo bar', et plantait avec une erreur en l'absence de valeur.
Avantages :
Inconvénients :
Ajout de la prise en charge des deux syntaxes et vérification de la longueur de @ARGV, autorisation des drapeaux-switch.
Avantages :
Inconvénients :