Take a look at Data::Dumper or Data::Dump (and many others of similar nature). Both of these modules define functions that iterate through arbitrarily deeply nested data structures — and they don't even require that they be purely hashes-of-hashes or arrays-of-arrays!
>perl -wMstrict -le
"my %ds = (
X => [ { one => 1 }, { two => 2, three => 3 }, ],
Y => [ { fee => 'fie' }, { foe => 'fum' }, { foo => 'bar' }, ],
);
;;
use Data::Dumper;
print Dumper \%ds;
"
$VAR1 = {
'X' => [
{
'one' => 1
},
{
'three' => 3,
'two' => 2
}
],
'Y' => [
{
'fee' => 'fie'
},
{
'foe' => 'fum'
},
{
'foo' => 'bar'
}
]
};