2016-10-17 37 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散列中返回密钥的顺序。

如果您稍微详细地解释您正在尝试做什么,那么我们可能会帮助您更多。