2010-09-17 8 views
28

¿Es la siguiente la mejor manera de comprobar si una variable escalar se inicializa en Perl, usando defined?¿Cómo verifico si una variable escalar de Perl se ha inicializado?

my $var; 

if (cond) { 
    $var = "string1"; 
} 

# Is this the correct way? 
if (defined $var) { 
    ... 
} 
+0

¿Qué problema estás tratando de resolver? –

+0

Comprobar 'undef' es la mejor manera de ver si una variable se ha inicializado o no; sin embargo, esto no pasaría la prueba de inicialización si la variable se establece en 'undef' en cualquier momento después de ser inicializada, como se indica a continuación. – vol7ron

Respuesta

29

Perl no ofrece una manera de comprobar si es o no una variable se ha inicializado.

Sin embargo, las variables escalares que no se han inicializado explícitamente con algún valor tienen el valor de undef de forma predeterminada. Tiene razón al decir que defined es la forma correcta de comprobar si una variable tiene o no un valor de undef.

Hay muchas otras maneras. Si desea asignar a la variable si es undef, que el código de ejemplo parece indicar, que podría, por ejemplo, el uso de Perl-o definido operador:

$var //= 'a default value'; 
+12

Los operadores '//' y '// =' se introdujeron en Perl 5.10. Para versiones anteriores, los operadores '||' y '|| =' hacen lo mismo, excepto que sobrescribirán un valor "definido pero falso" inicializado como '" 0 "' o '" "'. – mob

+1

Disculpe, pero los escalares son 'undef' por defecto, y el operador' defined' es lo que Perl ofrece para comparar con ese valor sin incurrir en una advertencia de "Uso de variable no inicializada". (Porque todos tienen '-w' y' use strict' en efecto, ¿no?) – Blrfl

+4

Blrfl: Eso es correcto. Ese es tu punto sin embargo? Un escalar que tenga un valor de undef no tiene ninguna relación con si se ha inicializado o no, ya que perl no puede distinguir en absoluto entre escalares y escalares no inicializados que tienen el valor 'undef' porque alguien lo estableció en' undef'. – rafl

5

Si no te importa si está vacío o no, lo es. De lo contrario, puede marcar

if (length($str || '')) {} 
1

'defined' devolverá true si una variable tiene un valor real.

Como acotación al margen, en un hash, esto puede ser cierto:

if(exists $h{$e} && !defined $h{$e}) 
+1

'undef' es un valor real. Usarlo como indicador de "sin valor" es, aunque común, solo una convención. – rafl

+0

"valor real" como en un valor escalar o de referencia válido. – msbmsb

+0

No existe un escalador no válido en Perl. – rafl

3

depende de lo que planea hacer con el variable ya sea que esté definido o no; a partir de Perl 5.10, puede hacerlo (desde perl51000delta):

Se ha implementado un nuevo operador // (defined-or). La siguiente expresión:

$a // $b 

es simplemente equivalente a

defined $a ? $a : $b 

y la declaración

$c //= $d; 

ahora se puede utilizar en lugar de

$c = $d unless defined $c; 
9

Depende de lo que trates de hacer. La forma correcta de hacer las cosas C es inicializar las variables cuando se declaran; Sin embargo, Perl is not C, así que uno de los siguientes puede ser lo que quiere:

1) $var = "foo" unless defined $var;  # set default after the fact 
    2) $var = defined $var? $var : {...};  # ternary operation 
    3) {...} if !(defined $var);    # another way to write 1) 
    4) $var = $var || "foo";     # set to $var unless it's falsy, in which case set to 'foo' 
    5) $var ||= "foo";      # retain value of $var unless it's falsy, in which case set to 'foo' (same as previous line) 
    6) $var = $var // "foo";     # set to $var unless it's undefined, in which case set to 'foo' 
    7) $var //= "foo";      # 5.10+ ; retain value of $var unless it's undefined, in which case set to 'foo' (same as previous line) 


C manera de hacer las cosas (no se recomienda):

# initialize the variable to a default value during declaration 
# then test against that value when you want to see if it's been changed 
my $var = "foo"; 
{...} 
if ($var eq "foo"){ 
    ... # do something 
} else { 
    ... # do something else 
} 

Otra manera de largo aliento de hacer esto es para crear una clase y una bandera cuando la variable ha sido cambiada, lo cual es innecesario.

Cuestiones relacionadas