Pregunta

Tengo un fragmento en esta forma:

my $a = $some_href->{$code}{'A'}; # a number or undef
my $b = $some_href->{$code}{'B'}; # a number or undef
$a = 0 unless defined($a);
$b = 0 unless defined($b);
my $total = $a + $b;

La realidad es aún más complicado, ya que más de dos variables se refiere.

Lo que realmente quiero escribir es la siguiente:

my $total = $some_href->{$code}{'A'} + $some_href->{$code}{'B'};

y tengo undef evalúa correctamente a 0 pero consigo estas advertencias en casi cada carrera:

Use of uninitialized value in addition (+) at Stats.pm line 192.

¿Cuál es la mejor manera de hacer que estos mensajes desaparecen?

Nota: I '' 'usar estrictas advertencias de uso' y si es relevante que s

.
¿Fue útil?

Solución

Es bueno que usted está utilizando strict y warnings. El propósito de las advertencias es para avisarle cuando Perl ve un comportamiento que es probable que sea intencional (y por lo tanto incorrecto). Cuando estás haciendo deliberadamente, que está perfectamente bien para desactivar la alerta a nivel local. undef se trata como 0 en contextos numéricos. Si estás bien con ambos con valores no definidos y que ellos evalúan a cero, simplemente desactivar la advertencia:

my $total;
{
  no warnings 'uninitialized';
  $total = $some_href->{$code}{A} + $some_href->{$code}{B};
}

Nota:. Desactivar sólo las advertencias que necesita, y lo hacen en el ámbito más pequeño posible

Si usted es reacio a deshabilitar las advertencias, hay otras opciones. A partir de Perl 5.10 se puede utilizar el operador de // (definido o) para establecer los valores por defecto. Antes de que las personas a menudo usan el || (lógico-o), pero que puede hacer lo incorrecto de los valores que se evalúan como falso. La forma más robusta a los valores predeterminados en la pre-5.10 versiones de Perl es comprobar si están defined.

$x = $y // 42;             # 5.10+
$x = $y || 42;             # < 5.10 (fragile)
$x = defined $y ? $y : 42; # < 5.10 (robust)

Otros consejos

Puede desactivar la advertencia “no inicializado” por un segundo:

my $a;
my $b = 1;
{
    no warnings 'uninitialized';
    my $c = $a+$b; # no warning
}
my $c = $a+$b; # warning

O bien, puede causar un cortocircuito a cero:

my $d = ($a||0)+$b; # no warning

No se ve muy agradable para mí, sin embargo.

Como se va a añadir ellos sólo tiene que filtrar los undefs.

use List::Util 'sum';

my $total = sum (0, grep {defined} $some_href->{$code}{'A'}, $some_href->{$code}{'B'});

O incluso

use List::Util 'sum';

my $total = sum (0, grep {defined} map {$some_href->{$code}{$_}} 'A', 'B');
my $a = $some_href->{$code}{'A'} || 0;
my $b = $some_href->{$code}{'B'} || 0;
my $total = $a + $b;

En este caso, está bien para tratar los falsos valores los mismos que los valores no definidos, debido a su valor de retorno.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top