Pregunta

Aquí hay algunos Perl simples para contar la cantidad de veces que ocurre un valor en una matriz. Esto se ejecuta sin advertencias.

use warnings;
use strict;

my @data = qw(1 1 2 3 4 5 5 5 9);
my %histogram;
foreach (@data)
{
    $histogram{

Aquí hay algunos Perl simples para contar la cantidad de veces que ocurre un valor en una matriz. Esto se ejecuta sin advertencias.

$histogram{

Aquí hay algunos Perl simples para contar la cantidad de veces que ocurre un valor en una matriz. Esto se ejecuta sin advertencias.

use warnings;
use strict;

my @data = qw(1 1 2 3 4 5 5 5 9);
my %histogram;
foreach (@data)
{
    $histogram{

Aquí hay algunos Perl simples para contar la cantidad de veces que ocurre un valor en una matriz. Esto se ejecuta sin advertencias.

<*>

Cuando el cuerpo del bucle se cambia a

<*>

Perl advierte "Uso de valor no inicializado además".

¿Qué está pasando debajo del capó? ¿Por qué se inicializa el valor cuando se suministra como un operando al operador ++ y no se inicializa con el operador +?

}++; }

Cuando el cuerpo del bucle se cambia a

<*>

Perl advierte "Uso de valor no inicializado además".

¿Qué está pasando debajo del capó? ¿Por qué se inicializa el valor cuando se suministra como un operando al operador ++ y no se inicializa con el operador +?

} = $histogram{

Aquí hay algunos Perl simples para contar la cantidad de veces que ocurre un valor en una matriz. Esto se ejecuta sin advertencias.

use warnings;
use strict;

my @data = qw(1 1 2 3 4 5 5 5 9);
my %histogram;
foreach (@data)
{
    $histogram{

Aquí hay algunos Perl simples para contar la cantidad de veces que ocurre un valor en una matriz. Esto se ejecuta sin advertencias.

<*>

Cuando el cuerpo del bucle se cambia a

<*>

Perl advierte "Uso de valor no inicializado además".

¿Qué está pasando debajo del capó? ¿Por qué se inicializa el valor cuando se suministra como un operando al operador ++ y no se inicializa con el operador +?

}++; }

Cuando el cuerpo del bucle se cambia a

<*>

Perl advierte "Uso de valor no inicializado además".

¿Qué está pasando debajo del capó? ¿Por qué se inicializa el valor cuando se suministra como un operando al operador ++ y no se inicializa con el operador +?

} + 1;

Cuando el cuerpo del bucle se cambia a

<*>

Perl advierte "Uso de valor no inicializado además".

¿Qué está pasando debajo del capó? ¿Por qué se inicializa el valor cuando se suministra como un operando al operador ++ y no se inicializa con el operador +?

}++; }

Cuando el cuerpo del bucle se cambia a

<*>

Perl advierte "Uso de valor no inicializado además".

¿Qué está pasando debajo del capó? ¿Por qué se inicializa el valor cuando se suministra como un operando al operador ++ y no se inicializa con el operador +?

¿Fue útil?

Solución

El operador + evalúa tanto el formulario a la izquierda como el formulario a la derecha del mismo, luego devuelve la suma de ambos. La evaluación de la llamada hash no ve ningún contexto especial.

El operador ++ tiene una magia especial incorporada. Cita de la página de manual de perlop, con respecto al operador ++:

  

" undef " siempre se trata como numérico y, en particular, se cambia a 0 antes de incrementar (de modo que un incremento posterior de un valor undef devolverá 0 en lugar de " undef ").

edit : para elaborar la diferencia, ++ cambia el valor en su lugar, mientras que + solo toma sus argumentos como entrada. Cuando + ve un valor indefinido, generalmente algo ha salido mal, pero para ++, su ejemplo de manipulación de hash es muy típico: el usuario quiere tratar undef como 0, en lugar de tener que verificar e inicializar cada vez. Parece que tiene sentido tratar a estos operadores de esta manera.

Otros consejos

No es que Perl necesariamente inicialice valores, sino que no siempre advierte sobre ellos. No intentes pensar en una regla para esto porque siempre encontrarás excepciones, y justo cuando creas que lo has resuelto, la próxima versión de Perl cambiará las advertencias sobre ti.

En este caso, como dijo Harleqin, los operadores de incremento automático tienen un caso especial.

Ciertos operadores omiten deliberadamente el "no inicializado" advertencia para su conveniencia porque se usan comúnmente en situaciones donde un 0 o " " el valor predeterminado para el operando izquierdo o único tiene sentido.

Estos son: ++ y - (pre o post), + =, - =,. =, | =, ^ =, & amp; & amp; =, || =.

Tenga en cuenta que algunos de estos dan la advertencia erróneamente cuando se usan en una variable vinculada: vea las pruebas marcadas TODO en http://perl5.git.perl.org/perl.git/blob/HEAD:/t/op/assignwarn.t .

Como Brian mencionó: todavía lo hace, solo te advierte. Las advertencias le informan sobre ciertas manipulaciones con efectos que quizás no haya deseado.

Usted está específicamente preguntando por el valor de $ histogram {$ _} , agregando 1 y luego asignándolo a la misma ranura. Es de la misma manera que no esperaría que la autovivificación funcione aquí:

my $hash_ref = $hash_for{$key_level_1};
$hash_ref->{$key_level_2} = $value;

como lo hace aquí:

$hash_for{$key_level_1}{$key_level_2} = $value;

Magic probablemente no funciona como la optimización. Y el compilador optimizador notaría que a = a + 1 es lo mismo que a ++ , por lo que si hubiera un operador de incremento en el lenguaje ensamblador, podría usar esa instrucción optimizada en su lugar de pretender que necesitaba preservar el primer valor y luego sobrescribirlo porque en realidad no es necesario.

La optimización es un escrutinio adicional y una sobrecarga una vez para mejorar el rendimiento en cada ejecución. Pero no hay garantía en un lenguaje dinámico de que no esté agregando gastos generales a la misma velocidad que de lo contrario estaría tratando de reducirlo.

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