TTaJTa4
TTaJTa4

Reputation: 840

Getting the inner hash in Perl

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

Answers (2)

ikegami
ikegami

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

choroba
choroba

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

Related Questions