Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problems with hash

Status
Not open for further replies.

jsscott

MIS
Oct 11, 2002
1
US
When I run a virtual (on free bsd) I receive this error:
virtual ./ccdb1Script2.pl
[Tue Jun 19 15:08:11 2001] ccdb1Script2.pl: Odd number of elements in hash assignment at ./ccdb1Script2.pl line 20.
Line twenty initializes my hash:
%postInputs = readPostInputs;

sub readPostInput{

$countyName = $postInputs{'countyName'};
$state = $postInputs{'state'};
$pAddress1 = $postInputs{'pAddress1'};
$pAddress2 = $postInputs{'pAddress2'};
$city = $postInputs{'city'};
$zip = $postInputs{'zip'};
$sAddress1 = $postInputs{'sAddress1' };
$sAddress2 = $postInputs{'sAddress2'};
$genInfoPhone = $postInputs{'genInfoPhone'};
$url = $postInputs{'url'};
$countyURL = $postInputs{'countyURL'};
$recOnLine = $postInputs{'recOnLine'};
$time = $postInputs{'time'};

$dbh->do("INSERT INTO county
VALUES($countyName, $state, $pAddress1, $pAddress2, $city,
$zip, $sAddress1, $sAddress2, $genInfoPhone, $url, $countyURL, $recOnLine, $time)");
$dbh->disconnect;

my (%searchField, $name, $buf, $pair, @pairs);

if ($ENV{'REQUEST_METHOD'} eq 'POST'){
read(STDIN, $buf, $ENV{'CONTENT_LENGTH'});
@pairs = split(/&/, $buf);

foreach $pair(@pairs)
{
($name, $val) = split(/=/,$pair);
$val = ~ tr/+/ /;
$val = ~ s/%([\a-fA-f0-9][\a-fA-F0-9])/pack("C", hex($1))/eg;
$name = ~ tr/+/ /;
$name = ~ s/%([\a-fA-f0-9][\a-fA-F0-9])/pack("C", hex($1))/eg;
$searchField{$name} = $val;

}
return (%searchField);
}
}
Do you see what I may be doing to cause this error? I have three separate books I am using, and they all give me bits and pieces but not the whole picture.
Thanks
 
You can't return a hash from a function like that. You need to use references or return the hash as an array. The returned array is assigned into the hash with the even numbered elements (0, 2, 4, ...) being the keys and the odd elements as the values (element 1 is the value for the key in element 0, etc.)
Code:
sub somefunc1 {
	return ("d", 4, "a", 1, "c", 3);
}

sub somefunc2 {
	my @array = ("d", 4, "a", 1, "c", 3);
	return (@array);
}

my %hash = ();

%hash = somefunc1;
print "somefunc1:\n";
foreach $k (keys %hash) {
	print "\t$k => $hash{$k}\n";
}

%hash = somefunc2;
print "somefunc2:\n";
foreach $k (keys %hash) {
	print "\t$k => $hash{$k}\n";
}

In your code, I would replace %searchField with @searchField and replace the line:
Code:
$searchField{$name} = $val;
with:
Code:
push @searchField, $name, $val;
Maybe @searchField should be initialized to a null list
too?

At the end just return @searchField instead of %searchField.
 
The first thing I see is that your call to "readPostInputs" is an incorrect call to a subroutine - done this way, Perl doesn't even know you are trying to call a subroutine. You need to add the parenthesis:

Change this:

%postInputs = readPostInputs;

To this:

%postInputs = readPostInputs();

Also, as sackyhack said, you "shouldn't" return a hash - I'm not sure you "can't", but you should't. It is safer and more predictable when you want to pass or return hashes, to pass or return hash *references* instead:

$postInputs_ref = readPostInputs();

sub readPostInputs {
blah
blah
return \%postInputs; ### the backslash in front of the % creates a reference to the hash


Once you have $postInputs_ref returned, you can either just use the reference to refer to hash elements like:

print "County Name is $postInputs_ref->{countyName}\n";

Or you can turn the reference back into a hash if you like that way of refering to hash elements better, like:

my %new_postInputs = %{$postInputs_ref};
print "County Name is $new_postInputs{countyName};

Personally, I prefer the first approach(using the reference to refer to hash elements) since it is cleaner and takes less resources(you don't have to create *another* hash from a reference to the first hash).

HTH.
Hardy Merrill
Mission Critical Linux, Inc.
 
I certainly do appreciate the input. I am printing your responses as I type so I can refer back and give it a whirl using your suggestions. I will let you know how it turns out.
Jean
 
I've done some testing and it looks like like I was completely wrong about returning hashes. My 'solution' would work, but only as well as your original code. I think the first problem pointed out in hmerrill's post is probably your problem. If you want to call a sub that is declared later in the program than the call, you need the following () or a leading & do indicate a subroutine call.

It would also probably be a good idea for both of us (me and jsscott)to get more comfortable with references.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top