sub rekey { my $h = shift; for my $k (keys %$h) { next unless ref $$h{$k}; my %n; for my $e (@{$$h{$k}}) { die "duplicate key '$$e{name}'" if exists $n{$$e{name}}; $n{$$e{name}} = $e; rekey($e); } $$h{$k} = \%n; } } rekey( $foo );