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.