比较foreach语句中分配的变量的问题

时间:2012-02-12 17:20:40

标签: perl mod-perl

我一直在研究一个cgi文件,该文件将检查用户是否想要注册其凭据时是否已经使用了用户名。如果使用用户名,则应该通知他们,如果不是,则将其凭据保存到原始平面文件。我无法比较我在foreach语句中赋值的变量。我告诉foreach如果用户输入的名称与已存储的名称相同,则为变量分配用户名。我让它正确地分配变量,但在单词之后我想告诉它在foreach之外再次比较这些变量,所以操作只进行一次。这是我目前的代码

#!/usr/bin/perl 
use warnings;
use strict;
use CGI qw(:standard);
use CGI::Carp qw/fatalsToBrowser warningsToBrowser/;
use Digest::MD5 qw(md5 md5_hex md5_base64);

#telling what variables are still to be used as global
our ($username, ,$user, $nametaken);

#assigning some local variables
my $username = param("username");
my $password = param("password");
my $hashpass = md5_hex($password);

print header, start_html();

#creating an array from the flatfile that usernames and passwords are stored
my @users = do { open my $fh, "<", "password.txt" or die $!; map { chomp; split /:/ } <$fh> };

#comparing the values in the array to the username entered
foreach my $user (@users) {
if ($user eq $username) {
    #printing here to test if it is comparing correctly which it is
    print p("$user\n");
    #assigning the $user value to $nametaken so it can be compared to later
    my $nametaken = $user;
    #printing here to test if the variable was correctly assigned, which it is
    print p("$nametaken\n");
    }
}   

#printing here to test if the variable was correctly assigned, which it is not printing
#so the foreach must be causing some king of issue for this variable after it is done and I don't know what that is
print p("$nametaken\n");

#Here is where I am trying to check if the username already exists and then save the user credentials if it does not
if ($nametaken eq $username) {
print p("Username already taken, Try again");
}

#As of now the else statement is running everytime and saving new user credentials even if a username is already taken
else {
open  my $fh, ">>", "password.txt" or die $!;
print $fh "$username:$hashpass\n";
print p("Your account has been created sucessfully");
close $fh;

}
print end_html();

3 个答案:

答案 0 :(得分:4)

您在$nametaken循环内部声明了一个新的词法范围变量foreach - 或者更确切地说,在if {}块内:my $nametaken = $user;

它可能与您在外面的$nametaken变量共享相同的名称,但它是一个完全不同的变量,具有if块的范围 - 一旦退出if,变量完全被遗忘了。无论你赋予它什么价值都会丢失。

您可以在此处查看有关词法范围变量的更多详细信息:

http://perldoc.perl.org/perlsub.html#Private-Variables-via-my%28%29


要以战术方式解决您的问题,您只需在if:my;

中删除$nametaken=$user声明即可

要以Perl方式正确地执行此操作,您应该重新考虑解决问题的方法。您可以使用foreach循环来检测列表中是否有值,但它绝对不是最好的(可读性方面,有时甚至是性能方面的)Perl技术。更惯用的方法是使用哈希查找:

my %users = map { ($_ => 1) } @users; # Create a hash with users being keys
if ($users{$username}) {
    print "$username already taken!\n";
}

答案 1 :(得分:3)

my $nametaken = $user;

创建一个名为$nametaken new 变量,该变量与您在循环外声明的$nametaken无关。

答案 2 :(得分:2)

$nametaken没有foreach循环之外的值的原因是因为它在词法范围内仅在foreach内定义。


总有不止一种方法可以做到:

my ( $nametaken ) = grep { /$username/ } @users;

if ( $nametaken ) { ...  } else { ... }

或简单地说:

if ( grep { /$username/ } @users ) { ... } else { ... }

当Perl中的临时变量较少时,通常噪声较小。