2010-08-18 7 views
9

Je viens de remarquer un comportement étrange de perl5 (5.10.0) quand j'ai passé 0 comme argument de ligne de commande à un script, qui l'assigne à une variable. Le problème que j'ai rencontré est que si je donne à la variable une valeur par défaut dans mon script qui est supérieure à 0, disons 1, je peux passer n'importe quelle valeur sauf 0 pour remplacer la valeur par défaut 1.problème passant 0 comme argument de ligne de commande

Voici le code de « test.pl » je:

#!/usr/bin/perl -w 
my $x = shift || 1; 
print "x is $x\n"; 

Suite sont les commandes et ouputs quand je l'ai testé:

$ ./test.pl 2 
x is 2 
$ ./test.pl 0 
x is 1 

Je vous en serais reconnaissant si quelqu'un peut faire la lumière sur ce point. Merci. wwl

Répondre

15

Si vous voulez $x avoir la valeur de « 1 » dans le cas où aucun argument est fourni, utilisez ceci:

my $x = shift // 1; 

de perldoc perlop:

« // » est exactement la même chose que « || », sauf qu'il teste le côté de définition des modèles de la main gauche au lieu de sa vérité .

Note: la définition ou l'opérateur est disponible à partir de 5,10 (publié le 18 Décembre, 2007)

+2

Ne pas oublier 'utilisation 5.10.0,' –

+0

J'ai le sentiment que cela a été introduit dans toute une version récente de Perl, pouvez-vous Dites lequel? Ensuite, je vais +1. –

+0

@gbacon: Merci. Comme plusieurs d'entre nous sont encore sur les versions antérieures, pourriez-vous le mentionner dans votre réponse s'il vous plaît eugene y? Merci. –

7

L'expression shift || 1 choisit le rhs si l'on évalue que lhs est "faux". Puisque vous passez 0, qui évalue à « false », $x se termine avec la valeur 1.

0

Dans cette ligne my $x = shift || 1; le changement a échoué le test et donc la condition logique OU || a été exécuté et affecté 1 à ... selon la page sur shift la valeur était 0 qui implique un tableau vide ....

3

utilise l'opérateur defined-or, car la chaîne "0" est définie, mais pas évaluée comme vraie.

#!/usr/bin/perl -w 
my $x = shift // 1; 
print "x is $x\n"; 
+0

Oui, mais comme mention de gbacon dans un commentaire ailleurs, cela nécessite Perl 5.10 ou plus tard. –

+2

j_random_hacker: Wayne utilise 5.10.0, qui a 2.5 ans. –

+0

Bon point Alexandr! :) –

6

La meilleure approche est celle de son eugène et les réponses de Alexandr, mais si vous êtes coincé avec un perl vieux, utilisez

my $x = shift; 
$x = 1 unless defined $x; 

Parce que vous avez un seul argument optionnel, vous pouvez examiner @ARGV dans un contexte scalaire pour vérifier combien d'arguments de ligne de commande sont présents. Si elle est là, l'utiliser, ou autrement se replier sur la valeur par défaut:

my $x = @ARGV ? shift : 1;