Uso de valor não inicializado
Esse é um dos alertas (warnings) mais comuns que você encontrará ao executar programas em Perl.
É só um alerta, que não fará seu programa parar, e será gerado apenas se a opção warnings estiver presente. O que é altamente recomendado.
A maneira mais comum de ligar os alertas é através da inclusão do comando use warnings; no começo de seu programa ou módulo.
O velho método é o de adicionar o parâmetro -w na primeira linha, que, em geral, se parece com essa:
#!/usr/bin/perl -w
Existem algumas diferenças, mas como use warnings está à disposição há mais de 12 anos, não há razão para evitá-lo. Em outras palavras:
Sempre use warnings;!
Vamos voltar agora ao alerta em questão.
Uma explicação rápida
Use of uninitialized value $x in say at perl_warning_1.pl line 6. (Uso de valor não inicializado $x em say em perl_warning_1.pl linha 6.)
Isso significa que a variável $x não tem nenhum valor (seu valor é o valor especial undef). Ou ela nunca teve um valor, ou em algum momento lhe foi atribuído o valor undef.
Você deveria dar um olhada quando a variável recebeu seu último valor, ou pelo menos tentar entender por que aquela parte do código nunca foi executada.
Um exemplo simples
O exemplo seguinte vai gerar o alerta em questão:
use warnings; use strict; use 5.010; my $x; say $x;
Perl é muito legal, e irá nos dizer qual arquivo gerou o alerta, e em qual linha.
Somente um alerta
Como eu disse, isso é só um alerta. Se o programa tem mais comandos depois do say, eles serão executados:
use warnings; use strict; use 5.010; my $x; say $x; $x = 42; say $x;
Isso vai imprimir
Use of uninitialized value $x in say at perl_warning_1.pl line 6. 42
Ordem confusa na saída
Tenha cuidado, no entanto, se seu código tem comandos antes da linha que gera o alerta, como neste exemplo:
use warnings; use strict; use 5.010; print 'OK'; my $x; say $x; $x = 42; say $x;
O resultado pode ser confuso:
Use of uninitialized value $x in say at perl_warning_1.pl line 7. OK 42
Aqui, o resultado do primeiro say é visto depois do alerta, mesmo se ele foi chamado antes do código que gerou o alerta.
Esse comportamento estranho é o resultado da buferização de ES (entrada e saída). Por padrão, Perl buferiza STDOUT, o canal padrão de saída, mas não buferiza STDERR, o canal padrão de erros.
Assim, enquanto a palavra 'OK' espera pelo despejo do buffer, a mensagem de alerta já chega à tela.
Desligando a buferização
Para evitar isso, você pode desligar a buferização da STDOUT.
Isso é feito com o seguinte código: $| = 1; no começo do programa.
use warnings; use strict; use 5.010; $| = 1; print 'OK'; my $x; say $x; $x = 42; say $x;
OKUse of uninitialized value $x in say at perl_warning_1.pl line 7. 42
(O alerta fica na mesma linha de OK porque não acrescentamos uma nova linha \n depois do OK.
O escopo indesejado
use warnings; use strict; use 5.010; my $x; my $y = 1; if ($y) { my $x = 42; } say $x;
Esse código também produz Use of uninitialized value $x in say at perl_warning_1.pl line 11.
Consegui cometer esse engano várias vezes. Sem prestar atenção, usei my $x dentro do bloco if, o que significa que criei outra variável $x, atribuí 42 a ela e usei-a fora do escopo no fim do bloco. (O $y = 1 serve apenas para guardar lugar para algum código de verdade em condições reais. Está aí apenas para fazer esse exemplo ficar um pouco mais realista.)
Existem, é claro, casos em que preciso declarar uma variável dentro de um bloco if, mas isso não acontece sempre. Quando o faço por engano, encontrar o erro torna-se uma atividade penosa.
Published on 2013-03-20