Question: I have Hash where values of keys are other Hashes.

Example: `{'key' => {'key2' => {'key3' => 'value'}}}`

How can I iterate through this structure?

Answer: 
The earlier answers show how to roll your own solution, which is good to do at least once so you understand the guts of how perl references and data structures work. You should definitely take a read through [perldoc perldsc](http://MooseX-Types-Ro) and [perldoc perlref](http://perldoc.perl.org/perlref.html) if you haven't already.

However, you don't need to write your own solution -- there is already a module on CPAN which will iterate through arbitrarily-complex data structures for you: [Data::Visitor](http://search.cpan.org/perldoc/Data::Visitor).
This is not really a new answer but I wanted to share how to do more than
just print all the hash values recursively but also to modify them if needed.

Here is my ever so slight modification of the dave4420's answer in which
the value is passed to the callback as a reference so my callback
routine could then modify every value in the hash.

I also had to rebuild the hash as the while each loop creates copies
not references.

```
sub hash_walk {
   my $self = shift;
    my ($hash, $key_list, $callback) = @_;
    while (my ($k, $v) = each %$hash) {
        # Keep track of the hierarchy of keys, in case
        # our callback needs it.
        push @$key_list, $k;

        if (ref($v) eq 'HASH') {
            # Recurse.
            $self->hash_walk($v, $key_list, $callback);
        }
        else {
            # Otherwise, invoke our callback, passing it
            # the current key and value, along with the
            # full parentage of that key.
            $callback->($k, \$v, $key_list);
        }

        pop @$key_list;
        # Replace old hash values with the new ones
        $hash->{$k} = $v;
    }
}

hash_walk(\%prj, [], \&replace_all_val_strings);

sub replace_all_val_strings {
    my ($k, $v, $key_list) = @_;
    printf "k = %-8s  v = %-4s  key_list = [%s]\n", $k, $$v, "@$key_list";
    $$v =~ s/oldstr/newstr/;
    printf "k = %-8s  v = %-4s  key_list = [%s]\n", $k, $$v, "@$key_list";
}

```