Also sprach Anno Siegel:
> Gupit <> wrote in comp.lang.perl.misc:
>> Unfortunately duplicate keys may have been specified in the lower
>> level hash structure as well. Replacing only the top level hash
>> structure wont help there.
>>
>> e.g. see key7 in the following example
>>
>> $hash = {
>> key1 => { key2 => val2,
>> key3 => val3,
>> },
>> key4 => [ vala,valb,],
>> key1 => {key5 => val5,
>> key6 => {
>> key7 => val7,
>> key8 => val8,
>> key7 => val9,
>> }
>> ),
>> };
>>
>> (I dont call this structure $hash in real life, I have simplified the
>> actual data structure here for ease of understanding and to retain the
>> focus of my question
)
>
> Well, if the problem re-appears at a lower level, re-apply the solution.
> In other words, re-design the data structure so that every hash that may
> have a key specified more than once is replaced with a list of pairs.
If we look at $hash->{key4}, regarding everything as a list likely has
its problems, too. The OP might be able to solve this with a
dispatch-table for particular entries. If he knows that there is always
a list associated with 'key4', then this is feasible. Here is a
spontaneous solution (might not be complete since it doesn't handle
structures within array-refs, only within hash-refs). And no, I do not
intend to win a beauty-award for it:
use Data:

umper;
use strict;
use vars qw($list);
eval "require 'config_file'";
my %dispatch;
# these hash-keys all have another hash-ref as value
@dispatch{ qw/key1 key2 key3 key5 key6 key6/ } =
(sub {
my ($key, $val, $hash) = @_;
die "Duplicate key '$key'\n" if exists $hash->{ $key };
if (@$val > 1) {
for (my $i = 0; $i <= $#$val; $i += 2) {
die "Duplicate key '$val->[$i]'\n"
if exists $hash->{ $key }->{ $val->[$i] };
if (! ref $val->[$i+1]) {
$hash->{ $key }->{ $val->[$i] } = $val->[$i+1];
} else {
$dispatch{$val->[$i]}->($val->[$i], $val->[$i+1], $hash);
}
}
} else {
$hash->{ $key } = $val;
}
}) x 6;
# takes an array-ref as value
$dispatch{ key4 } =
sub {
my ($key, $val, $hash) = @_;
if (exists $hash->{ $key }) {
die "Duplicate key '$key'\n";
}
$hash->{ $key } = $val;
};
my %hash;
for (my $i = 0; $i <= $#$list; $i += 2) {
$dispatch{$list->[$i]}->($list->[$i], $list->[$i+1], \%hash);
}
print Dumper \%hash;
For a config-file without duplicate values like this:
$list = [
key1 => [ key2 => 'val2',
key3 => 'val3',
key4 => 'val1',
],
key4 => [ qw/vala valb/ ],
key5 => [ key5 => 'val5',
key6 => 'val6'
],
];
it will correctly produce:
$VAR1 = {
'key5' => {
'key5' => 'val5',
'key6' => 'val6'
},
'key4' => [
'vala',
'valb'
],
'key1' => {
'key2' => 'val2',
'key4' => 'val1',
'key3' => 'val3'
}
};
and die when duplicate keys within a sub-structure are detected.
Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus}) !JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexi ixesixeseg;y~\n~~dddd;eval