在 Sub 中使用 "my" 时全局符号需要包名

Global Symbol requires package name while using "my" in Sub

我有一个 class 我们正在学习 Perl,所以如果我犯了 simple/obvious 错误,请原谅我,因为我还在学习。我的问题是为什么会出现错误

Global Symbol "%localhash" requires explicit package name

以及当我第一次在 Sub 中用 "my %localhash" 声明“$param”时出现相同的错误。

我的参考代码:

use strict;
use warnings;
use Exporter;
use vars qw(@ISA @EXPORT);

@ISA=qw(Exporter);
@EXPORT=("insert_user", "modify_user", "remove_user", "generate_list");


#Insert user Function
Sub insert_user{
    my $param = shift;
    my %localhash = %$param;
    print "Please enter Username: ";
    my $user_name = <>;
    chomp($user_name);
    if(exists ($localhash{$user_name})){ 
        print "Error, user already exists!";
        last;
    }
    $user_name =~ s/[^a-zA-Z0-9]//g;
    $user_name = lc($user_name);
    $localhash{$user_name};
    return %localhash;
    print "Please enter a password: ";
    my $user_password = <>;
    %localhash{$user_name} = $user_password;
    return %localhash;
}

在我的 class 中,我们假设使用 "my $param" 和 "my %localhash" 不同的时间,所以我会在每个 Sub 中重复相同的过程来声明 "my" 但我保留得到与 "my" 不存在时相同的错误。

您得到的第一个错误是syntax error at foo.pl line 13, near "my ";出现语法错误会导致 perl 的解析器关闭,之后您经常会收到虚假错误,因为它没有成功识别声明或对范围有误。忽略它们并修复语法错误(在这种情况下实际上是前面的几行:Sub 而不是 sub,正如 toolic 所指出的)。这会让你进入下一个错误:)

其他评论:

像你这样使用last是不好的;它将退出循环,但您的代码中没有循环。如果您的子程序是从一个循环中调用的,它将(带有警告)退出您的子程序并退出 that 循环,但这是导致错误的远距离操作。

很长一段时间以来,Exporter 都不需要子类化;只需 use Exporter 'import'; 而不是设置 @ISA.

除了 Sub 的问题,您还有 %localhash{$user_name} 而不是 $localhash{$user_name};你检查你的用户名是否已经存在 之前你去掉非字母数字字符并将其小写,这是错误的;并且您未能 chomp 密码。你也有很少的空白space,这可以使程序更具可读性

这就是我要写的东西

use strict;
use warnings;

use Exporter qw/ import /;

our @EXPORT = qw/ insert_user modify_user remove_user generate_list /;

sub insert_user {
    my ($param)   = @_;
    my %localhash = %$param;

    print "Please enter user name: ";
    my $user = <>;
    chomp $user;

    $user =~ s/[^a-zA-Z0-9]//g;
    $user = lc $user;
    if ( exists $localhash{$user} ) {
        warn "Error, user already exists!";
        return;
    }

    print "Please enter a password: ";
    my $pass = <>;
    chomp $pass;
    $localhash{$user} = $pass;

    return %localhash;
}