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

Nat*_*pos 0 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]
Run Code Online (Sandbox Code Playgroud)

我的代码是这样的:

#!/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);
Run Code Online (Sandbox Code Playgroud)

unu*_*tbu 5

这是引起问题的线.

my @array = shuffle(<$random_name>);
Run Code Online (Sandbox Code Playgroud)

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

open my $random_name, "<", "out.txt";
my @array = shuffle(<$random_name>);
Run Code Online (Sandbox Code Playgroud)


mik*_*grb 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: $!";
Run Code Online (Sandbox Code Playgroud)
  • 我删除了变量的预先声明.
  • 我更改了两个打开以使用括号并检查错误.
  • 我移动声明并将@array设置为刚刚out.txt打开后.
  • 由于@array设置后不需要$ random_file,我将在下一行关闭它.
  • 最后,我在关闭打开写入的Mail.txt时检查错误.检查您打开写入文件时close的返回值是非常重要的,因为某些错误(如写入文件时磁盘空间不足)在初始打开时将不会显示,但通过检查关闭可见($ fh)返回true.

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