2014-09-04 30 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