2012-03-07 12 views
6

Perché il mio codice non funziona dopo aver aggiunto use strict; use warnings;? C'è un modo per farlo funzionare?Come evitare errori con i parametri della riga di comando perl e usare strict

In precedenza, il codice di lavoro è:

#!/usr/bin/perl -s 
print "x: $x\n"; 
print "y: $y\n"; 

Il comando che ho incontrato è perl -s test.pl -x="hello" -y="world". L'output è:

x: hello 
y: world 

Tuttavia, dopo che ho aggiunto use strict; use warnings;, ho ottenuto i seguenti errori:

Variable "$x" is not imported at test.pl line 4. 
Variable "$y" is not imported at test.pl line 5. 
Global symbol "$x" requires explicit package name at test.pl line 4. 
Global symbol "$y" requires explicit package name at test.pl line 5. 
Execution of test.pl aborted due to compilation errors. 

so che ho bisogno di dichiarare my $x e my $y per fissare il 3 ° e 4 ° errore. Ma cosa significano i primi 2 errori e come posso superarli?

+1

Dedico un intero capitolo in _Mastering Perl_ alle opzioni (heh) qui. :) –

+0

la riga dello shebang è sbagliata; dovrebbe essere #!/usr/bin/env perl quindi usare strict; su una nuova linea per la massima portabilità –

+0

@briandfoy Verrebbe il capitolo 10 di _Mastering Perl_: 'Configurazione dei programmi Perl'? –

risposta

4

Si sta utilizzando un parser switch rudimentale perl -s, che utilizza variabili globali. Per farlo funzionare con use strict è necessario fare riferimento ai globals: $main::x come sottolineato da ruakh.

Ma anche così, le variabili lessicali (dichiarate con my) sono preferibili in quasi tutti i casi.Basta fare:

use strict; 
use warnings; 

my ($x, $y) = @ARGV; 
print "x: $x\n"; 
print "y: $y\n"; 

E utilizzare con:

perl test.pl hello world 

Per una più dettagliata e passare come la manipolazione, controlla il modulo Getopt::Long.

+0

Buona presa. Non ho notato "-s" nella mia fretta. +1 – DVK

+0

Ri: "Dubito che sia compatibile con' use strict' ": Lo è. Vedi la mia risposta qui sotto per come. :-) – ruakh

+0

Pura fortuna, sono morto in piedi. =) – TLP

2

Per comprendere il significato di QUALSIASI errore/avviso Perl, è possibile fare riferimento a perldiag.

In particolare, per "non è importato", si dice:

variabile "% s" % non viene importato s

(W vari) Con "use strict" a tutti gli effetti, hai fatto riferimento a una variabile globale che a quanto pare pensavi fosse importata da un altro modulo, perché qualcos'altro con lo stesso nome (di solito una subroutine) viene esportato da quel modulo. Di solito significa che metti il ​​buffo personaggio sbagliato nella parte anteriore della tua variabile.

In sostanza, Perl fatto 2 ipotesi distinte sulla tua non-dichiarato identifyer $x - sia

  1. una ("simbolo era pacchetto con ambito globale che è vietato essere utilizzato sotto strict globale "$ x" richiede pacchetto esplicito ")

  2. oppure era un tentativo di utilizzare la variabile di un altro pacchetto che avrebbe dovuto essere importata ma non lo era (" Variabile "$ x" non viene importata ").

Perl non può dire QUELLO delle due teorie sono corrette, quindi sputa entrambe le possibilità. L'ultimo errore (il simbolo globale "$ x" richiede il nome del pacchetto esplicito) era quello corretto in questo caso: era una variabile globale nel codice originale pre-strict.

9

In realtà, dichiarare queste variabili come variabili lessicali (my) non sarà di aiuto, perché è troppo "tardivo": lo switch le avrà già impostate. Esso definisce le variabili (package) globali (nel tuo caso, $main::x e $main::y, o — come abbreviazione speciale — $::x e $::y). Se non si desidera avere per riferirsi a loro usando i loro nomi dei pacchetti-qualificati, quindi è possibile utilizzare una dichiarazione our per indicare che i nomi nude $x e $y si riferiscono alla $x e $y nel pacchetto corrente:

our ($x, $y); 
print "x: $x\n"; 
print "y: $y\n"; 

(cappello-punta Dérobert per aver ricordato che è possibile utilizzare per questo our.)

in alternativa, è possibile copiare le variabili globali in variabili lessicali con nomi identici:

my ($x, $y) = ($::x, $::y); 
print "x: $x\n"; 
print "y: $y\n"; 

Questo si occuperà di entrambi i gruppi di diagnostica.

+2

'il nostro ($ x, $ y)' dovrebbe funzionare anche io, credo (non ho testato) – derobert

+0

@derobert: hai perfettamente ragione; Ho provato e ho rubato senza vergogna quello per la mia risposta. Grazie! :-) – ruakh

Problemi correlati