How should I store values in a multi-level Perl hash?
I am looking to do something like this. I remember I had some issues with values disappearing when programming like this. Is this type of structure "correct/valid" for a hash?
my %VAR;
$VAR{SCALAR} = "test scalar";
$VAR{ARRAY}[0] = "test array";
$VAR{HASH}{NAME}[0] = "test hash arr开发者_StackOverfloway 1";
$VAR{HASH}{NAME}[1] = "test hash array 2";
$VAR{HASH}{NAME}[2]{SOMEHASH} = "test hash array hash 1";
$VAR{HASH}{NAME}[2]{ANOTHERHASH} = "test hash array hash 2";
I see no reason why this wouldn't work. What issues are you seeing?
If you want to make sure your data structure looks like what you'd expect, I recommend something like Data::Dumper
:
# set up your %VAR hash as you like
use Data::Dumper;
print Dumper(\%VAR);
Should get something like:
$VAR1 = {
'HASH' => {
'NAME' => [
'test hash array 1',
'test hash array 2',
{
'ANOTHERHASH' => 'test hash array hash 2',
'SOMEHASH' => 'test hash array hash 1'
}
]
},
'ARRAY' => [
'test array'
],
'SCALAR' => 'test scalar'
};
This isn't exactly your question, but... if you're actually building the data structure in that fashion, you might consider a cleaner "literal" syntax:
#!/usr/bin/perl
use strict;
use warnings;
my %VAR = (
SCALAR => 'test scalar',
ARRAY => [
'test array',
],
HASH => {
NAME => [
'test hash array 1',
'test hash array 2',
{
SOMEHASH => 'test hash array hash 1',
ANOTHERHASH => 'test hash array hash 2',
},
],
},
);
The main two reasons are readability and autovivification bugs. That's not incorrect perl, but it can lead to hard-to-debug issues, such as accidentally typing:
$VAR{HASH}{NAME}[1] = "test hash array 1";
$VAR{HASH}{NAME}[2] = "test hash array 2";
$VAR{HASH}{NAME}[2] = "test hash array 3";
$VAR{HASH}{NAME}[4] = "test hash array 4";
instead of
$VAR{HASH}{NAME}[1] = "test hash array 1";
$VAR{HASH}{NAME}[2] = "test hash array 2";
$VAR{HASH}{NAME}[3] = "test hash array 3";
$VAR{HASH}{NAME}[4] = "test hash array 4";
Which can't be an issue if you're using
$VAR{HASH}{NAME} = [
undef,
'test hash array 1',
'test hash array 2',
'test hash array 3',
'test hash array 4',
];
Often when people complain about disappearing values it's because they replaced them. When you assign to any part of a hash, you replace the value that was there previously even if it was a reference value:
use 5.010;
use Data::Dumper;
my %hash;
$hash{key} = { qw(a 1 b 2) };
say Dumper( \%hash );
$hash{key} = 5;
say Dumper( \%hash );
The output shows that the hash reference that was the second level is no longer there:
$VAR1 = {
'key' => {
'a' => '1',
'b' => '2'
}
};
$VAR1 = {
'key' => 5
};
You just have to be careful what and where you assign things, just like you do with any other variable.
精彩评论