Global symbol “%formsequence” requires explicit package name at line 37

喜欢而已 提交于 2019-12-11 05:52:40

问题


I am trying to execute a Perl CGI script, but I am getting an error:

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

I did some research and found that use strict forces me to declare the variables before I use them or store any data, but in my program I have declared them and that is why I don't understand the error. Here is my script:

   #!/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";
                        }

                }

        }

回答1:


I suspect you may be viewing the concept of an 'array' from the perspective of a PHP developer. In Perl a hash and an array are separate data structures.

Arrays are declared using the @ prefix and you refer to elements using square brackets around an integer index:

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];
}

Hashes are declared using the % prefix and you refer to elements using curly braces around a string key:

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};
}

You wouldn't normally use the keys function on an array - in fact older versions of Perl don't even support it, newer versions will return a range of integers (e.g.: 0..2).

When you call keys on a hash the keys have no inherent order, and the order may change.

Other things worth knowing:

Using & to call a function is really old style (i.e. early 90s), these days we'd use readformdata() instead of &readformdata.

The != operator is a numeric comparison operator so only use it when the values you're comparing are actually numbers. If you want to check two strings are 'not equal' then use ne instead (e.g.: if($thing1 ne $thing2) { ... }).




回答2:


This seems to be some rather old Perl.

  • You use -won the shebang line rather than use warnings (which has been available since Perl 5.6.0 was released in 2000.
  • You use a (presumably) custom readformdata() function instead of CGI,pm's params() method. CGI.pm was added to the Perl core in 1997 (it was recently removed - but that's not a reason to not use it).
  • You use ampersands on function calls. These haven't been necessary since Perl 5 was released in 1994.

Your problem is caused by declaring an array, @formsequence, which you then try to access as a hash - $formsequence{$_} means, "look up the key $_ in the hash %formsequence. In Perl, arrays and hashes are two completely different data types and it is possible (although not recommended for, hopefully, obvious reasons) to have an array and a hash with the same name.

You declare arrays like this - using @:

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

And access individual element like this - using [...]:

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

You declare hashes like this - using `%':

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

And access individual elements like ths - using {...}:

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

Arrays are indexed using integers and are ordered. Hashes are indexed using strings and are unordered.

I can't really suggest a fix for your code as it's not really clear what you are trying to do. It appears that you want to check that parameters appear in a certain order, but this is doomed to failure as a) you can't guarantee the order in which CGI parameters are transmitted from the browser to your web server and b) you can't guarantee the order in which keys(%fields) will return the keys from your %fields hash.

If you explain in a little more detail what you are trying to do, then we might be able to help you more.



来源:https://stackoverflow.com/questions/40077049/global-symbol-formsequence-requires-explicit-package-name-at-line-37

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!