Questo warning è uno dei più comuni tra quelli che incontrerete eseguendo del codice Perl.
Essendo un warning, non impedisce l'esecuzione del vostro script e viene generato solo se i warning sono stati attivati, cosa che vi raccomando di fare.
Il modo più comune di attivare i warning è quello di includiere un'istruzione use warnings;
all'inizio del vostro script o modulo.
Il vecchio modo era invece quello di aggiungere un'opzione -w
sulla cosiddetta linea sh-bang, ovvero la prima
linea del vostro script contenente l'invocazione di perl:
#!/usr/bin/perl -w
Ci sono alcune differenze, ma siccome use warnings
è ormai disponibile da 12 anni,
non c'è alcuna ragione per non usarlo. In altre parole:
Usate sempre use warnings;
!
Torniamo al warning che volevo spiegare.
Una spiegazione veloce
Use of uninitialized value $x in say at perl_warning_1.pl line 6.
Il senso del messaggio è che la variabile $x
non ha un valore (o meglio, ha il valore speciale undef
).
Potrebbe non avere mai avuto un valore o averlo avuto prima che, ad un certo punto, le sia stato assegnato undef
.
Dovreste cercare il punto dove è stato fatto l'ultimo assegnamento alla variabile oppure cercare di capire perché un certo pezzo di codice non è stato eseguito.
Un semplice esempio
L'esempio seguente genera quel tipo di warning.
use warnings;
use strict;
use 5.010;
my $x;
say $x;
Perl è così gentile da dirci quale file ha generato il warning e a quale linea.
È solo un warning
Come ho già detto, questo è solo un warning. Se lo script ha altre istruzioni dopo l'istruzione
say
, tali istruzioni verranno eseguite:
use warnings;
use strict;
use 5.010;
my $x;
say $x;
$x = 42;
say $x;
Questo codice stampa
Use of uninitialized value $x in say at perl_warning_1.pl line 6.
42
Output in ordine sparso
Attenzione però che, se il vostro codice ha stampato qualcosa prima della linea dove viene generato il warning, come in questo esempio:
use warnings;
use strict;
use 5.010;
print 'OK';
my $x;
say $x;
$x = 42;
say $x;
il risultato potrebbe essere un po' strano.
Use of uninitialized value $x in say at perl_warning_1.pl line 7.
OK
42
Come vedete, il risultato della print
appare dopo
il warning, anche se essa è stata eseguita prima del
codice che ha generato il warning.
Questa anomalia è causata dal buffering dell'IO
.
DI default Perl applica il buffering a STDOUT, il canale standard di output,
mentre non lo applica a STDERR, il canale standard per i messaggi di errore.
Quindi, mentre la parola 'OK' è in attesa che il buffer venga svuotato, il messaggio di warning viene emesso sullo schermo.
Disattivare il buffering
Se volete evitare questo comportamento potete disattivare il buffering su STDOUT.
A questo scopo dovete aggiungere il seguente codice: $| = 1;
all'inizio dello script.
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
(Il warning è sulla stessa linea di OK perché non abbiamo emesso un carattere di a capo
\n
dopo OK.)
Lo scope indesiderato
use warnings;
use strict;
use 5.010;
my $x;
my $y = 1;
if ($y) {
my $x = 42;
}
say $x;
Anche questo codice genera Use of uninitialized value $x in say at perl_warning_1.pl line 11.
Mi è successo molte volte di commettere questo errore. Ho inserito distrattamente my $x
dentro al blocco if
, creando un'altra variabile $x e
assegnandole il valore 42 senza accorgermi che sarebbe uscita dal proprio scope alla fine del blocco.
(L'assegnamento $y = 1 sta al posto di un vero pezzo di codice e di una vera condizione.
Serve solo a rendere questo esempio un po' più realistico.)
Ovviamente in alcuni casi dichiaro la variabile nel blocco if perché è necessario, ma in altri casi no. E nei casi in cui la dichiaro per errore è difficile trovare il bug.