2009-10-24 50 views
0

我正在学习Perl,同时我正在为我的家庭事件创建一个程序,但是当我尝试使用随机化过程中的数组时,我收到了一些错误,如您所见:

[[email protected]:~/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. 
[[email protected]:~/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); 
+7

您似乎有一些很好的答案,但我希望如果您发布的代码较少,则会有更多的答案。感觉就像你说的那样“我的程序不能正常工作 - 为我调试!”如果您可以将其缩小到一个较小的5行程序(可能更多,取决于问题的复杂程度),以显示您获得的错误,则可能会发现您的问题得到更快速的回答。否则,它可能看起来(对一些人),就像你对你的问题投入很少或没有努力,这往往会使一些人恼火。 – 2009-10-24 02:44:51

+0

对不起,这是因为我要睡觉,我只是贴出来看看我什么时候醒来。对不起 – 2009-10-24 10:46:50

+1

事实证明,你的问题与阵列和随机化无关。我无法弄清楚如何正确地修改这个问题,以便在不删除大量代码的情况下帮助其他人。请自行修改,以便它可以成为其他类似问题的资源。 – 2009-10-24 12:47:48

回答

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

还有改进的空间,但这些都是biggies。不过,我必须说,你的代码对于一个刚接触Perl的人来说是一个很好的开始。使用use strict和warnings,foreach循环迭代散列键以及Getopt :: Long与尝试分析命令行参数自己很好看。

+1

我只会使用autodie pragma并自动完成所有错误检查;它也提高了可读性,因为没有太多的错误处理代码,这可能会让人分心。 – brunov 2009-10-24 03:53:12

+0

+1我自己同意并使用自动播放器,但我认为有价值显示自己动手的方法给某个新的...如果没有其他事情,以后才能正确欣赏autodie;) – mikegrb 2009-10-24 04:17:16

+0

非常感谢,你已经解释了非常好! ;) – 2009-10-24 11:16:46

3

在第17行,$random_name尚未初始化。您将在之后这条语句打开$random_name文件(第27行)。

5

这是导致问题的线路。

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

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

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

我想你在那里有一个错字,应该是'打开我的$ random_name'没有2 – mikegrb 2009-10-24 02:14:54

+0

@mikegrb:啊,是的,谢谢! – unutbu 2009-10-24 02:46:53

相关问题