John Ambers John Ambers - 1 month ago 15
Perl Question

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

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

}

}

Answer

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) { ... }).

Comments