Perché il mio script Perl si lamenta del "simbolo globale" $ random_name "richiede un nome di pacchetto esplicito"?

StackOverflow https://stackoverflow.com/questions/1616666

  •  06-07-2019
  •  | 
  •  

Domanda

Sto imparando Perl e allo stesso tempo sto creando un programma per i miei eventi familiari, ma quando sto cercando di usare un array con un processo di randomizzazione, ricevo alcuni errori, come puoi vedere:

[ubuntu@eeepc:~/Desktop/mail] ./get.pl -h pop.vix.terra.com.br -u nathanpc -p  (:D)
Global symbol "$random_name" requires explicit package name at ./get.pl line 17.
Execution of ./get.pl aborted due to compilation errors.
[ubuntu@eeepc:~/Desktop/mail]

E il mio codice è così:

#!/usr/bin/perl

# import packages
use Net::POP3;
use Getopt::Long;
use Mail::Message;
use List::Util qw(shuffle);
use strict;
use warnings;

# Variable declaration
my $host;
my $user;
my $pass;
my $email_file;
my $msg;
my @array = shuffle(<$random_name>);

# read command line options
# display usage message in case of error
GetOptions ('h|host=s' => \$host,
            'u|user=s' => \$user,
            'p|pass=s' => \$pass) or die("Input error. Try calling me with: -h <host> -u <username> -p <password>");

# file operations
open($email_file, ">>", "Mail.txt");
open my $random_name, "<", "out.txt";

# initiate connection
# default timeout = 120 sec
my $conn = Net::POP3->new($host) or die("ERROR: Unable to connect.\n");

# login
my $numMsg = $conn->login($user, $pass) or die("ERROR: Unable to login.\n");

# get message numbers
# iterate over list and print first 20 lines of each
if ($numMsg > 0) {
    my $msgList = $conn->list();
    foreach $msg (keys(%$msgList)) {
        my $rawdata = $conn->get($msg);
        my $msg_obj = Mail::Message->read($rawdata);
        my $body = $msg_obj->body;
        print $email_file $body;
        print $email_file "\n====================================================\n";
        print shift @array;
    }
} else {
    print "Mailbox is empty.\n";   
}

# close connection
$conn->quit();
close($email_file);
close($random_name);
È stato utile?

Soluzione

Le risposte di Greg Hewgill e ~ unutbu sono corrette. Volevo solo aggiungere che è meglio non pre-dichiarare le variabili, il che potrebbe aver aiutato un po 'a capire cosa non andava.

Ecco il tuo codice identico con alcune lievi modifiche:

#!/usr/bin/perl

# import packages
use Net::POP3;
use Getopt::Long;
use Mail::Message;
use List::Util qw(shuffle);
use strict;
use warnings;

# read command line options
# display usage message in case of error
my ($host, $user, $pass);
GetOptions ('h|host=s' => \$host,
            'u|user=s' => \$user,
            'p|pass=s' => \$pass) or die("Input error. Try calling me with: -h <host> -u <username> -p <password>");

# file operations
open (my $email_file, ">>", "Mail.txt") or die ("Error opening Mail.txt for write: $!");
open (my $random_name, "<", "out.txt") or die ("Error opening out.txt for read: $!");
my @array = shuffle(<$random_name>);
close($random_name);

# initiate connection
# default timeout = 120 sec
my $conn = Net::POP3->new($host) or die("ERROR: Unable to connect.\n");

# login
my $numMsg = $conn->login($user, $pass) or die("ERROR: Unable to login.\n");

# get message numbers
# iterate over list and print first 20 lines of each
if ($numMsg > 0) {
    my $msgList = $conn->list();
    foreach my $msg (keys(%$msgList)) {
        my $rawdata = $conn->get($msg);
        my $msg_obj = Mail::Message->read($rawdata);
        my $body = $msg_obj->body;
        print $email_file $body;
        print $email_file "\n====================================================\n";
        print shift @array;
    }
} else {
    print "Mailbox is empty.\n";
}

# close connection
$conn->quit();
close($email_file) or die "Error closing Mail.txt from write: $!";
  • Ho rimosso la dichiarazione preliminare delle variabili.
  • Ho cambiato le due aperture sia per usare la parentesi sia per verificare la presenza di errori.
  • Mi sono trasferito dichiarando e impostando @array subito dopo l'apertura di out.txt.
  • Dato che $ random_file non è necessario dopo aver impostato @array, lo chiudo nella riga successiva.
  • Infine, controllo la presenza di errori durante la chiusura di Mail.txt che è stato aperto per la scrittura. È molto importante controllare il valore di ritorno di close su un file che hai aperto per la scrittura poiché alcuni errori, come l'esaurimento dello spazio su disco durante la scrittura sul file, non verranno visualizzati nell'apertura iniziale ma saranno visibili controllando la chiusura ($ fh) restituito true.

C'è ancora spazio per migliorare, ma quelli erano i biggies. Devo dire però che il tuo codice è stato un buon inizio per qualcuno che non conosce Perl. Usando rigoroso e avvertimenti, il ciclo foreach per scorrere le chiavi dell'hash e Getopt :: Long vs cercando di analizzare da soli gli argomenti della riga di comando.

Altri suggerimenti

Questa è la linea che causa il problema.

my @array = shuffle(<$random_name>);

Devi definire $ random_name prima di usarlo. Prova

open my $random_name, "<", "out.txt";
my @array = shuffle(<$random_name>);

Alla riga 17, $ random_name non è ancora inizializzato. Dovresti mettere questa istruzione dopo il file $ random_name è aperto (riga 27).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top