Gx1sptDTDa
Gx1sptDTDa

Reputation: 1588

Perl - Why does looping over a hash by its keys and then printing each value result in a uninitialized warning?

Whenever I loop over a hash by its keys, and then printing each value, I get an "use of of uninitialized value in concatenation (.) or string..." warning. Even though the hash is clearly initialized up front. The output I want is printed, but I'd still like to know why this results in a warning, especially as accessing a value directly (outside of a loop) works without warnings.

#!/usr/bin/perl
use warnings;
use strict;

my %fruit = ();
%fruit = ('Apple' => 'Green', 'Strawberry' => 'Red', 'Mango' => 'Yellow');

#works
print  "An apple is $fruit{Apple} \n";

#gives warnings
foreach my $key (%fruit)
{
  print "The color of $key is $fruit{$key} \n";
}

#also gives warnings
foreach my $key (%fruit)
{
    my $value = $fruit{$key};
    print "$value \n";
}

Consider the above code. I guess perl sees a difference between the first print and the second print. But why? Why is there a difference between retrieving the value of a hash outside of loop and retrieving the value of a has inside of a loop?

Thanks!

Upvotes: 6

Views: 436

Answers (3)

user507077
user507077

Reputation:

Using a hash in list context yields both keys and values. Therefore the line foreach my $key (%fruit) iterates over key, value, key, value...

What you need is foreach my $key (keys %fruit).

Upvotes: 16

perlmonk
perlmonk

Reputation: 21

Use keys inside the for loop. e.g. foreach my $key (keys %fruit) ...

Upvotes: 2

slayedbylucifer
slayedbylucifer

Reputation: 23502

It should be foreach my $key ( keys %fruits ). I think this is what you actually want to do.

Upvotes: 2

Related Questions