2016-10-17 36 views
1

我試圖執行一個Perl CGI腳本明確包的名字,但我得到一個錯誤:全局符號「%formsequence」需要在37行

Global symbol "%formsequence" requires explicit package name at line 37. 

我做了一些研究,發現use strict力量我在我使用它們或存儲任何數據之前聲明變量,但在我的程序中我已經聲明瞭它們,這就是爲什麼我不明白這個錯誤。這是我的腳本:

#!/usr/bin/perl -w 

use strict; 

my %errors; 
my %form; 
my @formsequence; 

my %fields = (

     "lname" => "Last Name", 
     "phone" => "Phone", 
     "fname" => "Fist Name" 
     ); 

my %patterns = (

     "lname" => '[A-Z][a-z]{2,50}', 
     "phone" => '\d{3}-\d{3}-\d{4}', 
     "fname" => '[A-Z][A-Za-z]{2,60}' 
     ); 

@formsequence = ("lname", "phone", "phone"); 

print "content-type/html\n\n"; 

if ($ENV{REQUEST_METHOD} eq "POST") { 

     &readformdata; 
     if (&checkrequiredfields) { 

       print "Form Data validated successfully!"; 
     } 
     else { 
       foreach (keys (%fields)) { 

         if ($fields{$_} != $formsequence{$_}) { <-- line 37 
           $errors{$_}="Not in correct sequence\n"; 
         } 

       } 

     } 
+0

您聲明瞭一個數組,但稍後嘗試訪問它,就像它是一個散列一樣。 – dsm

+0

@dsm我想遍歷數組,所以我必須做'$ formsequence {$ _}'。 –

+1

@JohnAmbers你不能做'$ formsequence {$ _}',因爲你沒有一個名爲'%formsequence'的散列。你只有一個名爲'@ formsequence'的數組(你可以用'$ formsequence [$ integer]''來訪問這個數組。 –

回答

2

我懷疑你可能正在從PHP開發人員的角度查看「數組」的概念。在Perl中,散列和數組是獨立的數據結構。

陣列使用的是@前綴聲明,您是指使用圍繞整數索引方括號中的元素:

my @names = ('Tom', 'Dick', 'Larry'); 
say $names[0];  # 'Tom' 
say $names[-1];  # 'Larry' 
my $count = @names; # $count now equals 3 
foreach my $i (0..$#names) { 
    say $names[$i]; 
} 

哈希使用%前綴聲明,你指的是使用大括號圍繞一個字符串的關鍵要素:

my %rgb = (
    red => '#ff0000', 
    white => '#ffffff', 
    blue => '#0000ff', 
); 
say $rgb{'red'};  # '#ff0000' 
say $rgb{blue};  # '#0000ff' quotes optional around bareword keys 
foreach my $k (keys %rgb) { 
    say $rgb{$k}; 
} 

你通常不會使用keys功能的陣列上 - 其實老版本的Perl甚至不支持它,新版本將返回一個整數範圍(例如:0..2)。

當您在散列上調用keys時,這些密鑰沒有固有順序,並且順序可能會更改。

值得了解的其他事項:

使用&調用一個函數是真的舊式(即90年代初),這幾天我們會使用readformdata()代替&readformdata

!=運算符是數字比較運算符,所以只有當您比較的值實際上是數字時才使用它。如果您想檢查兩個字符串是否「不相等」,則使用ne代替(例如:if($thing1 ne $thing2) { ... })。

1

這似乎是一些相當老的Perl。

  • 您的家當行而不是use warnings(這已經可以因爲Perl 5.6.0 2000年
  • 發佈您可以使用(大概)定製readformdata()函數代替CGI,下午的params()方法使用-w 。在1997年,CGI.pm被添加到了Perl核心中(它最近被刪除 - 但這不是一個不使用它的理由)
  • 你在函數調用中使用了&符號,自Perl 5發佈以來,

您的問題是由聲明一個數組@formsequence引起的,然後您嘗試以散列的形式訪問 - $formsequence{$_}表示「在散列%formsequence中查找密鑰$_。在Perl中,數組和哈希是兩種完全不同的數據類型,並且有可能(儘管不推薦使用,希望是顯而易見的原因)具有相同名稱的數組和哈希。

你聲明這樣的陣列 - 使用@

my @array = ('foo', 'bar', 'baz'); 

和訪問單個元素這樣的 - 使用[...]

print $array[0]; # prints 'foo' 

你聲明這樣的哈希 - 用'%':

my %hash = (foo => 'Foo', bar => 'Bar', baz => 'Baz'); 

並訪問單個元素,如ths - usin g {...}

print $hash{foo}; # prints 'Foo' 

使用整數對數組進行索引並進行排序。散列使​​用字符串進行索引並且無序。

我不能真正爲你的代碼提出修正建議,因爲它不太清楚你想要做什麼。看起來你想檢查參數是否以某種順序出現,但這注定會失敗,因爲a)你無法保證CGI參數從瀏覽器傳輸到你的web服務器的順序,b)你可以' t保證keys(%fields)將從您的%fields散列中返回密鑰的順序。

如果您稍微詳細地解釋您正在嘗試做什麼,那麼我們可能會幫助您更多。