Question

I was asked to modify some existing code to add some additional functionality. I have searched on Google and cannot seem to find the answer. I have something to this effect...

%first_hash = gen_first_hash();
%second_hash = gen_second_hash();
do_stuff_with_hashes(%first_hash, %second_hash);

sub do_stuff_with_hashes
{
    my %first_hash = shift;
    my %second_hash = shift;

    # do stuff with the hashes
}

I am getting the following errors:

Odd number of elements in hash assignment at ./gen.pl line 85.
Odd number of elements in hash assignment at ./gen.pl line 86.
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 124.
Use of uninitialized value in concatenation (.) or string at ./gen.pl line 143.

Line 85 and 86 are the first two lines in the sub routine and 124 and 143 are where I am accessing the hashes. When I look up those errors it seems to suggest that my hashes are uninitialized. However, I can verify that the hashes have values. Why am I getting these errors?

Was it helpful?

Solution

The hashes are being collapsed into flat lists when you pass them into the function. So, when you shift off a value from the function's arguments, you're only getting one value. What you want to do is pass the hashes by reference.

do_stuff_with_hashes(\%first_hash, \%second_hash);

But then you have to work with the hashes as references.

my $first_hash  = shift;
my $second_hash = shift;

OTHER TIPS

A bit late but,

As have been stated, you must pass references, not hashes.

do_stuff_with_hashes(\%first_hash, \%second_hash);

But if you need/want to use your hashes as so, you may dereference them imediatly.

sub do_stuff_with_hashes {
    my %first_hash = %{shift()};
    my %second_hash = %{shift()};
};

Hash references are the way to go, as the others have pointed out.

Providing another way to do this just for kicks...because who needs temp variables?

do_stuff_with_hashes( { gen_first_hash() }, { gen_second_hash() } );

Here you are just creating hash references on the fly (via the curly brackets around the function calls) to use in your do_stuff_with_hashes function. This is nothing special, the other methods are just as valid and probably more clear. This might help down the road if you see this activity in your travels as someone new to Perl.

First off,

 do_stuff_with_hashes(%first_hash, %second_hash);

"streams" the hashes into a list, equivalent to:

 ( 'key1_1', 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ... )

and then you select one and only one of those items. So,

 my %first_hash = shift;

is like saying:

 my %first_hash = 'key1_1'; 
 # leaving ( 'value1', ... , 'key1_n', 'value1_n', 'key2_1', 'value2_1', ... )

You cannot have a hash like { 'key1' }, since 'key1' is mapping to nothing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top