2010-08-18 11 views
9

Acabo de notar un comportamiento extraño de perl5 (5.10.0) cuando pasé 0 como el argumento de la línea de comandos a un script, que lo asigna a una variable. El problema que encontré es que si le doy a la variable un valor predeterminado en mi script que es mayor que 0, digamos 1, entonces puedo pasar cualquier valor excepto 0 para anular el valor predeterminado 1.problema pasando 0 como argumento de línea de comandos

A continuación se muestra el código de 'test.pl' solía:

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

los siguientes son los comandos y ouputs cuando lo probé:

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

lo agradecería si alguien puede arrojar luz sobre esto. Gracias. wwl

Respuesta

15

Si quieres $x tener el valor de "1" en caso de que se proporciona ningún argumento, utilice esto:

my $x = shift // 1; 

de perlop perldoc:

"//" es exactamente lo mismo que "||", excepto que pone a prueba definedness del lado izquierdo en lugar de su verdad.

Nota: el definido o el operador está disponible a partir de 5,10 (lanzado el 18 de diciembre de 2007)

+2

No se olvide 'uso 5.10.0;' –

+0

Tengo una sensación de que esto se introdujo en una versión bastante reciente de Perl, se puede decir cual? Entonces voy a +1. –

+0

@gbacon: Gracias. Dado que algunos de nosotros todavía estamos en versiones anteriores, ¿podría mencionar esto en su respuesta, por favor, eugene y? Gracias. –

7

La expresión shift || 1 elige el rhs si el lhs lo evalúa como "falso". Puesto que usted está de paso 0, lo que se evalúa como "falsa", $x termina con el valor 1.

0

En esta línea my $x = shift || 1; el cambio no pasó la prueba y por lo tanto el condicional lógico OR || fue ejecutado y asigna 1 a él ... según la página en shift el valor era 0, lo que implica una matriz vacía ....

3

use defined-or operator, porque la cadena "0" está definida, pero no se ha evaluado como verdadera.

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

Sí, pero como menciona gbacon en un comentario en otro lugar, esto requiere Perl 5.10 o posterior. –

+2

j_random_hacker: Wayne usa 5.10.0, que tiene 2.5 años. –

+0

¡Buen punto, Alexandr! :) –

6

El mejor enfoque es el de Eugene y respuestas de Alexandr, pero si le pegan con un Perl más antiguos, utilice

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

Debido a que tiene un solo argumento opcional, se puede examinar @ARGV en contexto escalar para verificar cuántos argumentos de línea de comandos están presentes. Si está ahí, lo utilizan, o no caer de nuevo en el valor predeterminado:

my $x = @ARGV ? shift : 1; 
Cuestiones relacionadas