Reputation: 840
After spending a lot of time on debugging and understanding the reason for the code behavior, I decided to ask for help. It should be something very basic, but I can't seem to understand the reason why it works (actually does not work) like this. A piece of the code:
use Data::Dumper;
my (%p_all,%e_all);
get_e(\%e_all);
my %e_abs = $e_all{"ex_abs"};
my %e = $e_all{"ex"};
print Dumper(\%e_abs);
sub get_e{
my ($ex_href) = @_;
my $counter = 5;
my $exec1 = "ABC";
my $exec2 = "xyz";
$ex_href->{"ex_abs"}{$exec1} += $counter;
$ex_href->{"ex"}{$exec2} += $counter;
}
Output:
$VAR1 = {
'HASH(0x9e2a20)' => undef
};
If Ill try to do:
my %e_abs = %{$e_all{"ex_abs"}};
It will fail with the following error:
can't use an undefined value as a HASH reference
How can I solve this issue?
Upvotes: 1
Views: 47
Reputation: 386696
Always use use strict; use warnings qw( all );
; it would have identified the problem.
Reference found where even-sized list expected at a.pl line 6.
Reference found where even-sized list expected at a.pl line 7.
Hash values can only be scalars, so you should be using the following:
my $e_abs = $e_all{ex_abs};
my $e = $e_all{ex};
print Dumper($e_abs);
Alternatively, you could allocate a hash and copy the keys and values from the old hash into the new one, but that's needlessly expensive. This would be done as follows:
my %e_abs = %{ $e_all{ex_abs} };
Upvotes: 3
Reputation: 242363
$e_all{ex_abs}
contains a hash reference, to assign it to a hash, you first need to dereference it:
my %e_abs = %{ $e_all{"ex_abs"} };
my %e = %{ $e_all{"ex"} };
Or, in more recent Perl versions,
my %e_abs = $e_all{"ex_abs"}->%*;
my %e = $e_all{"ex"}->%*;
It outputs
$VAR1 = {
'ABC' => 5
};
It won't fail with "Can't use an undefined value..." unless $e_all{ex_abs}
is undefined.
Note that with warnings on, Perl also tells me
Reference found where even-sized list expected at 1.pl line 10.
Reference found where even-sized list expected at 1.pl line 11.
Upvotes: 4