Warum wird mein Perl-Skript beschweren sich über „Globale Symbol“ $ random_name „erfordert explizite Paketnamen“?

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

  •  06-07-2019
  •  | 
  •  

Frage

Ich lerne Perl und zugleich ein Programm, um meine Familie Ereignisse Ich schaffe, aber wenn ich ein Array mit einer Randomisierung Prozess zu verwenden, versuche ich einige Fehler bin immer, wie Sie sehen können:

[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]

Und mein Code wie folgt aus:

#!/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);
War es hilfreich?

Lösung

Die Antworten von Greg Hewgill und ~ unutbu korrekt sind. Ich wollte nur hinzufügen, dass es am besten nicht zu Variablen vorab erklärt, dass ein bisschen geholfen haben zu verstehen, was falsch war.

Hier ist Ihr identischer Code mit einigen geringfügigen Änderungen:

#!/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: $!";
  • Ich entfernte die predeclaration von Variablen.
  • änderte ich die beiden Gebrauch Klammer und beide Fehlerprüfung sowohl öffnet.
  • Ich zog Deklarierung und Einstellung @array nur nach out.txt geöffnet wird.
  • Da $ random_file ist nicht erforderlich, nachdem @array gesetzt ist, ich es in der nächsten Zeile zu schließen.
  • Abschließend möchte ich auf Fehler überprüfen, wenn mail.txt schließen, die zum Schreiben geöffnet wurde. Es ist sehr wichtig, den Rückgabewert von knapp einer Datei überprüfen Sie zum Schreiben wie bestimmte Fehler geöffnet, wie der Speicherplatz laufen, während in die Datei zu schreiben, wird nicht in dem Anfang offen zu sehen sein wird, aber sichtbar sein durch, dass ein enge Kontrolle ($ fh) true zurückgegeben.

Es gibt immer noch Raum für Verbesserungen, aber das waren die biggies. Ich muß allerdings sagen, Ihr Code ein ziemlich guter Start für jemanden neu in Perl ist. Mit use strict und Warnungen an die foreach-Schleife über die Tasten des Hash-iterieren sowie Getopt :: Long vs versuchen, Befehlszeilenargumente zu analysieren sind selbst gut zu sehen.

Andere Tipps

Das ist die Linie, die das Problem verursacht.

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

Sie müssen $ random_name definieren, bevor es zu benutzen. Versuchen

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

In Zeile 17 wird $random_name noch nicht initialisiert. Sie wollen diese Aussage setzen nach die $random_name Datei geöffnet wird (Zeile 27).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top