2014-09-04 78 views
2

我是Perl新手,我无法完全了解我的代码出了什么问题。我相信我正确使用语法,但我怀疑问题可能是这一行:这是为什么复制或覆盖列表的内容?

push @students, \%information; 

我要的是对学生的名单包含的学生的信息哈希值。我期望的是,在每次添加学生后,都会创建学生信息的另一个散列并将其链接到列表的最新索引。但是,如果我同时输入了学生数据,最新的内容会覆盖前一个内容,因此当您打印它时,您会在上一个列表条目中看到最新输入信息的重复内容。如果我输入了1位学生并在添加后马上查看,然后输入了另一位学生,最新的学生将覆盖以前的学生。有人可以解释这一点吗?谢谢!

这是我的代码:

use strict; 
use warnings; 

my $userchoice = 0; 
my $i; 
my @students =(); #empty array 
my %information =(); 

while ($userchoice != 4) { 
    print "------------------------------\n"; 
    print "Welcome! What would you like to do?\n"; 
    print "[0]Create Student Record\n"; 
    print "[1]Edit Student Record\n"; 
    print "[2]View Student Record\n"; 
    print "[3]Delete Student Record\n"; 
    print "[4]Exit\n"; 
    print "Your Choice : "; 
    $userchoice = <STDIN>; 
    chomp($userchoice); 

    if ($userchoice == 0) { 
     print "-----------\n"; 
     print "CREATE STUDENT RECORD.\n"; 
     if ($#students <= 9) { 
      print "Name : "; 
      $information{"name"} = <STDIN>; 
      chomp($information{"name"}); 
      push @students, \%information; 
     } 
     print "Student Record Full. " if ($#students >= 10); 
    } 

    if ($userchoice == 2) { 
     print "\nVIEW STUDENTS.\n"; 
     print "[0]View One Student\n"; 
     print "[1]View All Students\n"; 
     print "[2]Back to Main Menu\n"; 
     print "Your Choice : "; 
     $userchoice = <STDIN>; 
     if ($userchoice == 1) { 
      print "VIEW ALL STUDENTS.\n"; 

      print "STUDENT 1---------------\n"; 
      print "Name : ", $students[0]->{"name"}, " \n"; 
      print "STUDENT 2---------------\n"; 
      print "Name : ", $students[1]->{"name"}, " \n"; 
     } 
    } 
} 
+2

您需要每次使用引用到一个新的哈希值,而不是试图引用相同的哈希每一次。最简单的方法是在循环体内定义'%information'。 – 2014-09-04 16:43:59

+1

要调试这样的问题,请在循环中使用'Data :: Dumper'。 – toolic 2014-09-04 16:50:27

+0

明白了!感谢乔纳森。它真的被重复,因为列表的排序引用相同的散列...谢谢! – ejandra 2014-09-04 17:00:55

回答

1

正如评论指出:

你需要使用一个参考每次都有一个新的散列,而不是每次都尝试引用相同的散列。最简单的方法是在循环体内定义%information

你的代码是目前:

my %information =(); 

while ($userchoice != 4) { 
    print "------------------------------\n"; 

这将正常工作(或者,至少,它这方面会正常工作),如果你使用:

while ($userchoice != 4) { 
    my %information =(); 
    print "------------------------------\n"; 
+0

正是我所做的,并且之后它正常工作。感谢您提供更多细节! – ejandra 2014-09-04 17:48:15

4

这始终推到阵列以相同的散列的引用push @students,\%information; 为了说明:

my %hash = (index => 0); 
my @list =(); 
foreach my $i (1..3) { 
    $hash{index} = $i; 
    push @list, \%hash; 
} 

for (my $i=0; $i<@list; $i++) { 
    print "item $i - $list[$i] - $list[$i]->{index}\n"; 
} 

通知从输出该地址是相同:

item 0 - HASH(0x4c8068) - 3 
item 1 - HASH(0x4c8068) - 3 
item 2 - HASH(0x4c8068) - 3 

您可以通过eith修复呃声明环

while($userchoice!=4){ 
    my %information =(); 

内部或通过强制一个新的参考%信息时,你推:

push @students, { %information }; 
2

您的问题出现因为您将每个学生的参考号码都放在阵列中:

push @students, \%information; 

一种解决方法是简单地创建一个新的匿名散列的每个记录:

push @students, { %information }; 

但是,我相信,你也可以使用一个教训限制了你的变量的范围。

声明变量时始终使用可能的最小范围。这既有助于记录您的代码,也可以减少意外滥用像这样的变量的机会。

以下是你的脚本的改写,以消除全球范围内使用的所有变量:

use strict; 
use warnings; 

my @students =(); #empty array 

while (1) { 
    print "------------------------------\n"; 
    print "Welcome! What would you like to do?\n"; 
    print "[0]Create Student Record\n"; 
    print "[1]Edit Student Record\n"; 
    print "[2]View Student Record\n"; 
    print "[3]Delete Student Record\n"; 
    print "[4]Exit\n"; 
    print "Your Choice : "; 
    chomp(my $userchoice = <STDIN>); 

    last if $userchoice == 4; 

    if ($userchoice == 0) { 
     print "-----------\n"; 
     print "CREATE STUDENT RECORD.\n"; 
     if (@students <= 10) { 
      print "Name : "; 
      chomp(my $name = <STDIN>); 
      push @students, { name => $name }; 
     } 
     print "Student Record Full. " if (@students > 10); 
    } 

    if ($userchoice == 2) { 
     print "\nVIEW STUDENTS.\n"; 
     print "[0]View One Student\n"; 
     print "[1]View All Students\n"; 
     print "[2]Back to Main Menu\n"; 
     print "Your Choice : "; 
     chomp(my $userchoice = <STDIN>); 
     if ($userchoice == 1) { 
      print "VIEW ALL STUDENTS.\n"; 

      for my $i (1 .. @students) { 
       print "STUDENT $i---------------\n"; 
       print "Name : ", $students[ $i - 1 ]{"name"}, " \n"; 
      } 
     } 
    } 
} 
+0

谢谢你的帮助提示。我会记住它。 – ejandra 2014-09-04 18:51:54