http://www.perlmonks.org?node_id=615049

opensourcer has asked for the wisdom of the Perl Monks concerning the following question:

I'm unable to print values of hash who is inside of another hash. I'm trying to print values of version and type.
$data = { data => 'hello', complicated => { version => 1, type => 'struct', }, req => 'Submit' }; foreach (keys %$data ) { if (ref($data->{$_})) { foreach (keys %{$data->{$_}}) { print " $_ : ".$data->{$_}->{$_}."\n"; } } }
can any 1 help me with this .

Replies are listed 'Best First'.
Re: printing refence of hash inside a hash
by Samy_rio (Vicar) on May 12, 2007 at 06:39 UTC

    Hi, try like this,

    $data = { data => 'hello', complicated => { version => 1, + type => 'struct', }, req => 'Submit' }; foreach my $first (keys %$data ) { if (ref($data->{$first})) { foreach my $second (keys %{$data->{$first}}) { print " $second : ".$data->{$first}->{$second}."\n"; } } }

    Regards,
    Velusamy R.


    eval"print uc\"\\c$_\""for split'','j)@,/6%@0%2,`e@3!-9v2)/@|6%,53!-9@2~j';

Re: printing refence of hash inside a hash
by liverpole (Monsignor) on May 12, 2007 at 14:13 UTC
    Hi opensourcer,

    What shmem points out is that you're apparently trying to use $_ to refer to 2 separate (distinct) variables, which you can't do.

    Samy_rio demonstrated one solution, which is to name the loop variable in each of the loops, so that there isn't a naming conflict.

    I wanted to mention an alternative way of viewing the contents of a (possibly complicated) data structure, which is quite commonly used -- Data::Dumper.

    For example:

    use strict; use warnings; use Data::Dumper; my $data = { data => 'hello', complicated => { version => 1, type => 'struct', }, req => 'Submit' }; print "Contents of \$data: ", Dumper($data), "\n";

    which prints:

    Contents of $data: $VAR1 = { 'req' => 'Submit', 'complicated' => { 'version' => 1, 'type' => 'struct' }, 'data' => 'hello' };

    s''(q.S:$/9=(T1';s;(..)(..);$..=substr+crypt($1,$2),2,3;eg;print$..$/
Re: printing refence of hash inside a hash
by shmem (Chancellor) on May 12, 2007 at 09:34 UTC
    print " $_ : ".$data->{$_}->{$_}."\n";

    So perl should figure out for you which $_ to use - the one from the inner loop first, then the outer, then the inner?

    for (qw(fine)) { for (qw(mess)) { print "$_ $_\n"; } } __END__ mess mess

    No "fine mess".

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: printing refence of hash inside a hash
by RL (Monk) on May 12, 2007 at 16:08 UTC

    The following is a bit carried away but I think it might be usefull one way or the other.

    As far as I know

    foreach (keys %$data ) { bla....

    causes $data to be deferenced on each iteration of the loop, which may become expensive if you have a huge amount of stuff in $data

    One may extract the keys before the loop, use a temporary array which will be used for the loop (and while freeing resources) like this:

    my @tmp_ary = keys %$data; while(my $item = shift @tmp_ary) { do stuff... }
    After the loop @tmp_ary will still be there but empty.

    Hope this helps
    RL