Storing a hash in a hash

I have problems with a Perl script. I am trying to store a hash in a hash. The script is trivial:

use Data::Dumper; my %h1=(); $h1{name}="parent"; my %h2=(); $h2{name}="child"; $h1{nested}=%h2; # store hash h2 in hash h1 print "h2:\n"; print Dumper(%h2); # works print "h1{nested}:\n"; print Dumper($h1{nested}); # fails 

Results:

 h2: $VAR1 = 'name'; $VAR2 = 'child'; h1{nested}: $VAR1 = '1/8'; 

Why is $ h1 {nested} not dumped as a hash, but as some kind of weird scalar (1/8)?

PS: even if this question sounds trivial - I searched for SO, but did not find that it was asked before. PPS: my Perl v5.10.1 (*) is built for x86_64-linux-gnu-thread-multi (with 53 registered patches, see perl -V for more details)

+4
source share
3 answers

You can store hashref in a hash:

 $h1{nested}=\%h2; 

and then you will get access to the name %h2 by doing

 $h1{nested}->{name} 

In your code,% h2 forcibly scans a context that shows you the value "1/8" and saves it.

+11
source

In perl, values ​​stored in a list (hash or array) are always scalars . Given this, the only way to save the hash inside another hash is to keep a reference to it.

 $h1{'nested'} = \%h2; 

and

 $h1{'nested'} = { 'name'=>'child' }; 

(the curly brackets on the right side are a reference to an anonymous hash).

By the way, in order not to quote literals in keys, it is usually considered bad practice, see here

+5
source

Why is $ h1 {nested} not dumped as a hash, but as some kind of weird scalar (1/8)?

Because you store it in a scalar context!

When you do this:

 $h1{nested} = %h2; 

You store a scalar. Since %h2 is a hash, you are provided with the ol fraction line. According to the Perldoc website

If you evaluate the hash in a scalar context, it returns false if the hash is empty. If there are key / value pairs, it returns true; more precisely, the return value is a string consisting of the number of buckets used and the number of buckets allocated, separated by a slash.

This explains the 1/8 you get.

What you need to do is save the hash as a reference in another hash. As others have pointed out, this should be:

 $h1{nested} = \%h2; 

The backslash in front of the hash name gives you the memory location in which the hash is stored. You can use curly braces, but I prefer the backslash.

Look at perldoc prelreftut on your computer (or on the webpage I am linked to). This will tell you how to do things like list of lists, hashes or hashes, lists of hashes and list hashes. Just the word o` warning: if you get too complicated, it will be hard to maintain, so once you have fun take a look at the perldoc Perl Orientation Programming Tutorial .

The perldoc command contains a lot of Perl documentation, including the entire Perl function, the Perl modules installed on your system, and even basic information about the Perl language.

+4
source

All Articles