1

I am trying to parse an array of arrays, but I get error

Reference found where even-sized list expected

Here is the program:

use Modern::Perl;

my @info=(
      ['k1','v1',1,2],
      ['k2','v2',2,3]
    );

my %names=getNames(\@info);

sub getNames {
    my ($info) = @_;
    my %names;
    foreach my $item (@$info) {
       $names{@$item[0]}=@$item[1];
    }
    return \%names;
}

2 Answers 2

4

As Ivan pointed out, your return value does not match what you're assigning it to:

my %names = getNames(\@info);

sub getNames {
    ...
    return \%names;
}

%names excepts an even number of elements because it's a hash, but you're assigning it a reference to a hash, which is a single element. Hence the error.

This line of your subroutine is also a little suspect: $names{@$item[0]}=@$item[1];. Perhaps you meant to use $names{$item->[0]}=$item->[1];?

If you're trying to translate the array of arrays into a hash with keys pointing at the remaining values, you can use the following:

my @info=(
      ['k1','v1',1,2],
      ['k2','v2',2,3],
    );

my %names = map {$_->[0] => [@{$_}[1..$#$_]]} @info;

use Data::Dump;
dd \%names;

Outputs:

{ k1 => ["v1", 1, 2], k2 => ["v2", 2, 3] }

If however, you're just wanting the first "value", then the following would be sufficient:

my %names = map {$_->[0] => $_->[1]} @info;
Sign up to request clarification or add additional context in comments.

Comments

3

The problem is that you're trying to assign hash reference to hash my %names=getNames(\@info);. Change it to work with reference:

my $names = getNames(\@info);

Or return hash:

return %names;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.