Почему мой Perl-скрипт жалуется на то, что «Глобальному символу« $ random_name »требуется явное имя пакета»? - PullRequest
0 голосов
/ 24 октября 2009

Я изучаю Perl и в то же время я создаю программу для семейных событий, но когда я пытаюсь использовать массив с процессом рандомизации, я получаю некоторые ошибки, как вы могли видеть:

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

И мой код такой:

#!/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);

Ответы [ 3 ]

5 голосов
/ 24 октября 2009

Эта строка вызывает проблему.

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

Вам необходимо определить $ random_name перед его использованием. Попробуйте

open my $random_name, "<", "out.txt";
my @array = shuffle(<$random_name>);
5 голосов
/ 24 октября 2009

Ответы Грега Хьюгилла и ~ Унутбу верны. Я просто хотел добавить, что лучше не объявлять переменные заранее, что могло бы немного помочь понять, что было не так.

Вот ваш идентичный код с небольшими изменениями:

#!/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: $!";
  • Я удалил предварительную декларацию переменных.
  • Я изменил два открытия, чтобы оба использовали круглые скобки и оба проверяли на ошибки.
  • Я перенес объявление и настройку @array сразу после открытия out.txt.
  • Поскольку $ random_file не нужен после установки @array, я закрываю его на следующей строке.
  • Наконец, я проверяю ошибки при закрытии Mail.txt, который был открыт для записи. Очень важно проверить возвращаемое значение close для файла, который вы открыли для записи, поскольку некоторые ошибки, такие как нехватка места на диске во время записи в файл, не будут видны при первоначальном открытии, но будут видны при проверке этого закрытия. ($ fh) вернул true.

Есть еще возможности для совершенствования, но это были большие достижения. Должен сказать, что ваш код стал хорошим началом для новичка в Perl. С использованием строгих и предупреждений приятно видеть цикл foreach для перебора ключей хеша, а также Getopt :: Long против попыток самостоятельного анализа аргументов командной строки.

3 голосов
/ 24 октября 2009

В строке 17 $random_name еще не инициализировано. Вы захотите поместить этот оператор после того, как откроется файл $random_name (строка 27).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...