Click the box titles below to expand:

How to's

XSLT

GOOGLE MAPS API

PHP

Perl

Document Object Model (DOM)

UNIX

Generic Mapping Tools (GMT)

Miscellaneous

Projects

Courses Taught

Latest Favorites

Mac OS X

Web Development

Beta

How To :: Perl :: Dealing with hashes in Perl

I am sorry, but I find Perl extremely esoteric and picky. However, I do have to use it quite often. One of things I hate most is casting variables, arrays and hashes (associative arrays). [2007-03-29 — I have written MUCH more Perl since I wrote that and I am liking it more and more.....] I much prefer PHP. Anyway, complaining aside, recently I had to process an old online form. In the form there is a hash called %FORM that contains all the form submission data. The site admins wanted the ability to add multiple select options and the Perl script to parse that information.

So we have multiple selects named account_type and list with multiple values. Here is how to process it:

  1. #!/path/to/perl
  2. .....
  3. my $buffer ;
  4. read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
  5.  
  6. my @pairs = split(/&/, $buffer);
  7.  
  8. my %FORM;
  9.  
  10. foreach my $pair (@pairs)
  11. {
  12. my( $name, $value ) ;
  13. ( $name, $value ) = split(/=/, $pair);
  14.  
  15. .....
  16.  
  17. if( $name eq 'account_type' ) {
  18. push( @{$FORM{'account_type'}}, $value ) ;
  19. } elsif( eq 'list' ) {
  20. push( @{$FORM{'list'}}, $value ) ;
  21. } else {
  22. $FORM{$name} = $value ;
  23. }
  24.  
  25. }

We use the values from account_type to determine what the subject line in a confirmation email is (among other things). Several options equate to this same thing (such as if you want a building account, backup account then these both are Mac accounts). To make sure that we don't get duplications in the subject line we do:

  1. .....
  2. my @type_list ;
  3. my %seen = () ; # record what we have seen
  4. foreach my $subj_act_type (@{$FORM{"account_type"}} )
  5. {
  6. if( $subj_act_type eq "igpphome" || $subj_act_type eq "trident" || $subj_act_type eq "popmail" )
  7. {
  8. unless( $seen{"Mac"} ) { # check if exists
  9. $seen{"Mac"} = 1 ;
  10. push( @type_list, "Mac" ) ;
  11. }
  12. }
  13. if( $subj_act_type eq "sun" )
  14. {
  15. push( @type_list, "Sun" ) ;
  16. }
  17.  
  18. }
  19. my $joined_type_list = join( ", ", @type_list ) ;
  20.  
  21. print MAIL "Subject: $joined_type_list New User Account Application\n\n";

The check to see if the array value exists is from the O'Reilly Perl Cookbook (4.6).
The interesting thing to notice is the foreach() part. The same goes for applying to listserves from this form:

  1. foreach my $mylist (@{$FORM{"list"}} )
  2. {
  3. print MAIL "add $FORM{"employees_email"} $mylist-at-host\n";
  4. }

These three code snippets show an interesting way of casting Perl variables, arrays and hashes.

The notation in the foreach() loop looks ugly, but it works well. Bascially you have to dereference the hash and recast it as a scalar, then recast that as an array. Yuck.

More information:

Credits: Thanks to Edgar Milik for showing me all this Perl malarky.

Disclaimer

This information is freely provided as–is. Messing around with the command line and creating files is a serious business, and I accept no liability for errors created, systems corrupted, or hard–disk damage by you following these instructions. They worked for me but may not work for you. Remember to back–up EVERYTHING before you try any of this stuff — it is not simple OR easy!!!

If you have any questions about this please email me at rlnewman@ucsd.edu and I will try my best to help you out.

made with CSS     Valid XHTML 1.0!      Valid CSS!