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

Hello Monks.

I was looking at this perl.com article and I didn't understand how to interpret some of the syntax used:
sub access_check { my $user_id = shift; my @allow_users = @_; my %quick_allow = map { $_ => 1 } @allow_users; return $quick_allow{ $user_id }; }

What is the map function doing? It effectively iterates through the array (storing each item in $_) and assigns a value of '1' to each? This results in an overall value of true? Zero would have been treated as false and the user wouldn't have been added to the array of allowed_users? Is this right?

I am also struggling to understand how to dereference code like this:
my %ALL_USER_GROUPS = ( 23 => [ qw( g1 g4 ) ], 13 => [ qw( g3 g5 ) ], );

With so many braces, brackets, parentheses, etc., it quickly becomes difficult to interpret the meaning of the code. Is there a strategy I should routinely employ? How does one name such complex structures? A hash of hashes of arrays? In naming that complex data structure, would I start with the %ALL_USER_GROUPS hash and then move to the right (looking at the numeric keys) before looking at the anonymous arrays)?

When dereferencing complex data structures, where do I start? How do I know when a reference ends and when to add another curly brace or sigil?

Thanks Monks.

Replies are listed 'Best First'.
Re: Need help with perl syntax.
by ikegami (Patriarch) on Mar 14, 2008 at 04:00 UTC
    my %quick_allow = map { $_ => 1 } @allow_users;

    means

    my @anon; for (@allow_users) { push @anon, do { $_ => 1 }; } my %quick_allow = @anon;

    which does

    my %quick_allow; for (@allow_users) { $quick_allow{$_} = 1; }

    my %ALL_USER_GROUPS = ( 23 => [ qw( g1 g4 ) ], 13 => [ qw( g3 g5 ) ], );

    is a HoA. It could have been written

    my %ALL_USER_GROUPS = ( # key value # ----- --------------- '23', [ 'g1', 'g4' ], '13', [ 'g3', 'g5' ], );

    => implies a key-value relationship, and qw() just saves typing and clutter.


    When dereferencing complex data structures, where do I start? How do I know when a reference ends and when to add another curly brace or sigil?

    Deconstruct it one level at a time.

    # At the outmost level, you have a list of groups stored in a hash. # List the keys (group ids) and fetch the corresponding value (group m +embers). for my $gid ( keys %ALL_USER_GROUPS ) my $members = $ALL_USER_GROUPS{$gid}; print("Group: $gid\n"); # Now we want to dump the list of group members. for my $member (@$members) { print("Member: $member\n"); # That's it. } print("\n"); }

    Once you got that far, you can play with the formatting. For example, you could replace the inner loop with a join to print all the members on one line:

    for my $gid ( keys %ALL_USER_GROUPS ) my $members = $ALL_USER_GROUPS{$gid}; print("Group: $gid\n"); print("Members: ", join(' ', @$members), "\n"); print("\n"); }
         push @anon, do { $_ => 1 };

      push works just fine with a list, you don't need a  do {} block.

      push @anon, $_, 1;
        my @y = map { ... } @x;
        is more or less equivalent to
        my @anon; for (@x) { push @anon, do { ... }; } my @y = @anon;

        Yes it can be simplified, which I proceeded to do in the next snippet.

Re: Need help with perl syntax.
by grizzley (Chaplain) on Mar 14, 2008 at 14:10 UTC
Re: Need help with perl syntax.
by Anonymous Monk on Mar 14, 2008 at 04:00 UTC
      I personally think that this SoPW post was well written and that your reply was a bit too crass for someone who hasn't even bothered to register here. You did however offer a list of links that the SoPW author will undoubtedly find useful.
        Well you'd be wrong.