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

I just started trying complex structures in Perl, and Bi-Dimensional arrays and hashes.

I was making this form processor, and to be able to allow my co-workers (who have little idea about perl) to add form fields in the program without worrying about updating their use later in the program, so I hacked this piece of code:

%fields = ('1.Name' => $cgi->param('name') || 'Anonymous', '2.Email' => $cgi->param('email') || 'No email Supplied', '3.Comments' => $cgi->param('comments') || 'No Comments', '4.Satisfied' => $cgi->param('radio1') || 'Not Specified', );
In order to use later in the program
foreach (sort keys %names) { print "$_ : $names{$_} \n"; }

Why would using the %fields hash in a hash context

not work, and instead, using it in an array context works??

Is this always the way with hashes and references?? ( I might not be using the proper namings here ), or maybe it's the way I'm dereferencing the variable later??

Finally the code worked, but I need to get a grip of what happened, cuz I fixed it by mistake

Thanx


Chady | http://chady.net/

Replies are listed 'Best First'.
(tye)Re: Hashes and Refs
by tye (Sage) on Mar 08, 2001 at 02:13 UTC

    Common problem. "(" denotes a list, "[" creates an anonymous array out of a list, and "{" creates an anonymous hash out of a list. You initialize a hash (%fields) by giving it a list. Doing:

    my %fields= { a=>1, b=>2 };

    tries to init %fields with a list of one item, that is, tries to set the key to be a hash ref, {a=>1,b=>2}, and provides no value for that key. Just like you don't write:

    my @list= [ 0, 1, 2 ];

    unless you want an array that contains just one item (and that item is a reference to an anonymous array that contains 3 items).

    Does that help?

            - tye (but my friends call me "Tye")
      yes, thanx it does... I think I should read more about this
      Chady | http://chady.net/
Re: Hashes and Refs
by arturo (Vicar) on Mar 08, 2001 at 02:06 UTC

    I'm confuzled. Here, in no particular order, are the reasons why:

    • there isn't really such a thing as "hash context" (as distinct from list context) ... what you have in
      %fields = {'1. ...
      confuses the anonymous hash constructor {} with the proper parentheses (). (I got caught on this a lot when I started working with these things =)
    • you reference %fields above and below, and %names in the middle.
    • your %fields construction isn't a multilevel anything, it's just a regular hash.

    HTH

    Philosophy can be made out of anything. Or less -- Jerry A. Fodor

      Sorry for that.. I posted the code from the original file... it's supposed to be $fields later.
      and I thought that a {} will delimit hash elements, and () delimits array elements.
      so it's still a regular hash here...:(
      Chady | http://chady.net/

        Here's a way to think of it that helped me (though it's a little indirect, this is how I latched onto the difference): the => operator you see in hash construction is really just a comma that says "quote barewords to the left of me." So it's a pretty subtle difference between:

        my %hash = (1, 2, 3, 4, 5, 6);
        and
        my %hash = (1=>2, 3=>4, 5=>6);

        Both do the same thing; the only difference comes out if you want to have strings as the keys, using the => makes things look nicer, and lets the key/value relationship stand out visually =)

        my %quotes_hash = ("bob","carol", "ted","alice"); # vs. my %noquotes_hash = (bob=>"carol", ted=>"alice");

        In a lot of respects, hashes are just lists, at least as far as their construction is concerned ... of course the internals are different =)

        Philosophy can be made out of anything. Or less -- Jerry A. Fodor