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

A while ago I posted a similar question (each on reference is experimental at) regarding a hash of arrays.

Now I have the same thing with a hash of hashes

while ( my ( $key, $value ) = each $hoh{$name} ) { do stuff; }

This works with a warning but I cannot seem to fix it without no warnings 'experimental' I have tried  each %$hoh{$name} but it did not help.

Any help greatly appreciated. update, this is the content of one of these HoH:

$VAR105 = 'S-1-5-21-xxxxxxxx-xxxxxxxxx-xxxxxxxxxxxx-xxxxx'; $VAR106 = { 'mail' => 'user@domain.tld', 'objectsid' => 'S-1-5-21-xxxxxxxx-xxxxxxxxx-xxxxxxxxxxxx-x +xxx', 'proxyaddresses' => [ 'X400:c=TLD;a= ;p=Domain;o=Exchange; +s=name;g=fn;', 'SMTP:name@domain.tld', 'smtp:name@domain.tld' ], 'givenname' => 'name', 'displayname' => 'name surname', 'sn' => 'surname', 'distinguishedname' => 'CN=name surname,OU=users,DC=domain +,DC=tld' };
And I got it to work with this code:

while ( my ( $key, $value ) = each %{ $hoh{$sid} } ) { ... }
Strangely, when using  each %{ $hoh->{ $sid } } I get the error:

Global symbol "$hoh" requires explicit package name
O well, it works every time is this reference stuff easier to work with, but it still trips me every now and then :-) Thanks all (again).

Replies are listed 'Best First'.
Re: each on reference is experimental take 2
by Mr. Muskrat (Canon) on Mar 10, 2016 at 19:47 UTC

    Strangely, when using each %{ $hoh->{ $sid } } I get the error

    That's because you are trying to access the non-existent hashref $hoh instead of the existing hash %hoh.

    # Hash, this is what you have my %hoh = ( ... ); # walk each key/value pair contained in the hash reference stored in $ +hoh{$sid} while ( my ( $key, $value ) = each %{ $hoh{$sid} } ) { ... } # Hash reference, what generated the error my $hoh = { ... }; # walk each key/value pair contained in the hash reference stored in $ +hoh->{$sid} while ( my ( $key, $value ) = each %{ $hoh->{$sid} } ) { ... }
      aha, thanks for your explanation, I think I got it.
Re: each on reference is experimental take 2
by 1nickt (Canon) on Mar 10, 2016 at 18:30 UTC

    Hi natxo,

    Try dereferencing with full syntax:

    #!/usr/bin/perl use strict; use warnings; use feature 'say'; my $data = { name => { foo => 'bar', baz => 'qux' } }; while ( my ( $key, $val ) = each %{ $data->{'name'} } ) { say "$key: $val"; } __END__
    Output:
    foo: bar baz: qux

    Hope this helps!


    The way forward always starts with a minimal test.
Re: each on reference is experimental take 2
by hippo (Archbishop) on Mar 10, 2016 at 18:31 UTC

    each %{$hoh{$name}} works for me (in the sense that no warning about each is produced). Without an SSCCE it's impossible to tell if this will fix your particular problem, however.

Re: each on reference is experimental take 2
by Anonymous Monk on Mar 10, 2016 at 20:21 UTC

    Sounds like you might want to study perldsc a bit. As the other monks have already explained, the best and most compatible way to dereference the hashref is to use each %{ ... }.

    The "push/pop/splice/each on reference" feature (aka "autoderef") will be gone in Perl v5.24, so your first bit of code will only work (with a warning) on Perls v5.14 thru v5.22.

    As a possible replacement, the feature "Postfix Dereference Syntax" introduced in v5.20 will hopefully be pulled out of experimental status eventually:

    #!/usr/bin/env perl use warnings; use 5.020; use feature 'postderef'; no warnings 'experimental::postderef'; my %hoh = ( foo=>{a=>1,b=>2}, bar=>{c=>3,d=>4} ); for my $name (keys %hoh) { while ( my ($key,$value) = each $hoh{$name}->%* ) { say "$key: $value"; } }

    Unfortunately, since this feature is experimental too, there is no guarantee that it won't be removed as well. But this one does seem more likely to stay at the moment. I'm not sure if a decision has been made as to when it might come out of expiermental state.

      Update: Turns out postderef will no longer be experimental as of v5.24 (see here).