为什么我的Perl脚本会抱怨“全局符号”$ random_name“需要显式包名”?

时间:2009-10-24 01:13:22

标签: perl warnings

我正在学习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 个答案:

答案 0 :(得分:5)

这是造成问题的一条线。

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

您需要在使用之前定义$ random_name。尝试

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

答案 1 :(得分:5)

Greg Hewgill和~unutbu的答案是正确的。我只是想补充说,最好不要预先声明变量,这可能有助于理解错误。

以下是您的相同代码,稍作修改:

#!/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。
  • 由于@array设置后不需要$ random_file,我会在下一行关闭它。
  • 最后,我在关闭打开写入的Mail.txt时检查错误。检查您为写入而打开的文件的close的返回值非常重要,因为某些错误(如写入文件时磁盘空间不足)在初始打开时不会显示,但通过检查关闭可见($ fh)返回true。

还有改进的余地,但那些都是大人物。我必须说,你的代码对于Perl的新手来说是个不错的开始。使用use strict和warnings,foreach循环迭代哈希的键以及Getopt :: Long vs试图自己解析命令行参数很好看。

答案 2 :(得分:3)

在第17行,$random_name尚未初始化。在打开$random_name文件后,您需要将此语句放入。(