내 Perl 스크립트가 "전역 기호 "$random_name"에는 명시적인 패키지 이름이 필요합니다"라고 불평하는 이유는 무엇입니까?

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

  •  06-07-2019
  •  | 
  •  

문제

저는 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);
도움이 되었습니까?

해결책

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: $!";
  • 변수 사전 선언을 제거했습니다.
  • 괄호를 사용하고 오류를 확인하도록 두 개의 열기를 변경했습니다.
  • out.txt가 열린 직후에 @array를 선언하고 설정하도록 옮겼습니다.
  • @array를 설정한 후에는 $random_file이 필요하지 않으므로 다음 줄에서 닫습니다.
  • 마지막으로 쓰기용으로 열어둔 Mail.txt를 닫을 때 오류가 있는지 확인합니다.파일에 쓰는 동안 디스크 공간 부족과 같은 특정 오류는 초기 열기에는 표시되지 않지만 닫기를 확인하면 표시되므로 쓰기 위해 연 파일에 대한 닫기 반환 값을 확인하는 것이 매우 중요합니다. ($fh)는 true를 반환했습니다.

아직 개선의 여지가 있지만 그게 가장 큰 문제였습니다.하지만 당신의 코드는 Perl을 처음 접하는 사람에게는 아주 좋은 시작이었습니다.엄격한 사용과 경고를 사용하여 해시 키를 반복하는 foreach 루프와 Getopt::Long을 비교하여 명령줄 인수를 직접 구문 분석하는 것이 좋습니다.

다른 팁

이것은 문제를 일으키는 선입니다.

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

사용하기 전에 $ random_name을 정의해야합니다. 노력하다

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

17 행, $random_name 아직 초기화되지 않았습니다. 이 진술을하고 싶을 것입니다 ~ 후에 그만큼 $random_name 파일이 열렸습니다 (27 행).

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top