Perl: How to get a reference to the value associated with a key in a hash

Viewed 27

Say I have a hash referred to by h, which contains the key a. I want to map b to a hash. I could do this directly using $h->{b}{key} = 123 but if I am inserting multiple key/value pairs, it is inefficient because I am doing the $h->{b} lookup multiple times, and also wordy. It's not too bad if there's only two levels, but in my script I actually have multiple levels of hashes. For example:

$h1->{one}{two}{key} = 123

What I'd like to be able to do is get a reference to the location of the value associated with the key. If there's already a hash, it should refer to the hash; if there's nothing there, the interpreter should construct a hash for me. Here's what I tried:

#!/usr/bin/perl -l

use Data::Dumper;

# create a hash
$h = {a => 1};
print Data::Dumper->Dump([$h], ["h"]);

# take a reference to the value associated with key "b"
$bref = \$h->{b};
print 'bref = '. $bref;
print Data::Dumper->Dump([$bref], ["bref"]);

# construct a hash and assign its address to the location pointed to by bref -- the value associated with "b" in the hash
$$bref->{foo} = 10;
$$bref->{bar} = 20;
$$bref->{baz} = 30;
print 'bref = '. $bref;
print Data::Dumper->Dump([$bref], ["bref"]);

# it doesn't work
$h = {a => 1};
print Data::Dumper->Dump([$h], ["h"]);

Unfortunately, it doesn't work. bref refers to the constant value undef; when I dereference it as a hash, the interpreter does construct a hash, but it is standalone, not inside h. Here is the output of the script:

  ~/perl: perl ref-to-hash-value
$h = {
       'a' => 1
     };

bref = SCALAR(0x13b50f8)
$bref = \undef;

bref = REF(0x13b50f8)
$bref = \{
            'foo' => 10
          };

$h = {
       'a' => 1
     };

Is there a way to do what I want? Or is there another solution to the problem I described?

1 Answers

My script had a bug: I am reassigning h to a new hash on the last-but-one line. When I remove that line, it works:

  ~/perl: perl ref-to-hash-value
$h = {
       'a' => 1
     };

bref = SCALAR(0x98c0f8)
$bref = \undef;

bref = REF(0x98c0f8)
$bref = \{
            'baz' => 30,
            'foo' => 10,
            'bar' => 20
          };

$h = {
       'b' => {
                'baz' => 30,
                'foo' => 10,
                'bar' => 20
              },
       'a' => 1
     };
Related