mehturt
mehturt

Reputation: 302

Perl hash of arrays clarification

I need clarification on how hash of arrays works. I'm trying to add one element array to a hash and then retrieve it.

#!/usr/bin/perl -w

use strict;
use diagnostics;

my %h;
my $key = "a";
my $val = "x";

push @{ $h{$key} }, $val;
print "1: " . $h{$key} . "\n";
print "2: " . $h{$key}[0] . "\n";

my @arr = $h{$key};
print "3: " . $arr[0] . "\n";

This prints out:

1: ARRAY(0x8ffe98)
2: x
3: ARRAY(0x8ffe98)

I'm wondering what is the difference between line 2 and line 3, thanks.

Upvotes: 1

Views: 105

Answers (3)

Miller
Miller

Reputation: 35198

You're being slightly confused by this assignment, since you're assigning the array reference to an array:

my @arr = $h{$key};
print "3: " . $arr[0] . "\n";

The above assignment is equivalent to:

my ($ref) = $h{$key};
print "3: " . $ref . "\n";

Which as you can tell visually, is the same as your print #1.

If you'd like to assign the values of your reference to your new array, you will have to dereference it:

my @arr = @{$h{$key}};

However, modifications to your new array @arr will not effect your original data structure.

Upvotes: 1

clt60
clt60

Reputation: 63902

The question is already answered, but for help you should to use some data-dumping utility, what helps visualise what happens. For example Data::Dumper or Data::Printer .

e.g. with Data::Printer

#!/usr/bin/perl -w
use strict;
use diagnostics;
use DDP;

my %h;
my $key = "a";
my $val = "x";

p %h;
push @{ $h{$key} }, $val;
p %h;

my @arr = $h{$key};
p @arr;

prints:

{}

{
    a   [
        [0] "x"
    ]
}

[
    [0] [
        [0] "x"
    ]
]

with Data::Dumper

#!/usr/bin/perl -w

use strict;
use diagnostics;
use Data::Dumper;

my %h;
my $key = "a";
my $val = "x";

print Dumper \%h;
push @{ $h{$key} }, $val;
print Dumper \%h;

my @arr = $h{$key};
print Dumper \@arr;

prints similar output

$VAR1 = {};
$VAR1 = {
          'a' => [
                   'x'
                 ]
        };
$VAR1 = [
          [
            'x'
          ]
        ];

Upvotes: 1

user2864740
user2864740

Reputation: 61875

my @arr = $h{$key}; is creating an array of a single element - the array-ref, just as if it had been written as my @arr = ( $h{$key} );. That is, the expression does not otherwise dereference the array-ref.

Thus $arr[0] (#3) evaluates to the same value as $h{$key} (#1) and not $h{$key}[0] (#2).

Instead, consider this form with a dereference where the resulting list is assigned to the array variable:

my @arr = @{ $h{$key} };

(Now $arr[0] will be the same as $h{key}[0].)

Upvotes: 1

Related Questions