How To Store Lists in Cookie Hash Values
#!/usr/bin/perl -w

##  Warning!!!  No book ANYWHERE will show you this trick so you MUST keep
##  this page!!  It shows how to retain form elements whose param calls
##  return *lists*!!  Cookie hash values CANNOT be references so you must
##  use the join/split tricks shown below!

use CGI qw(:standard :netscape);
use CGI::Carp qw(fatalsToBrowser); # Makes die work acceptably! Very important!!
use CGI::Cookie;

@citystate = ("Portland,Oregon", "Seattle,Washington", "San Diego,California",
              "Reno,Nevada", "Las Vegas,Nevada", "Las Cruces,New Mexico",
              "Ashland,Oregon", "Wells,Nevada", "Death Valley,California");
 
%param = cookie("data");

foreach ('name', 'sports', 'weather')
{
    $param{$_} = param($_) || $param{$_} if /name/;
    $param{$_} = (join("#", param($_)) || $param{$_}) if !/name/; 
}     

$go = param('go');
($go eq "yes") ? ($exp = "-1d") : ($exp = "+30d");
$cookie = cookie(-name => "data", -value => \%param, -expires => "$exp");

print header(-cookie => $cookie), start_html;

if (!param)
{

print start_form,
      p("Enter name: ", textfield(-name => 'name', -value => $param{name})),
      p("Favorite sport: ", checkbox_group(-name => 'sports',
                  -values   => ['baseball', 'football', 'basketball', 'hockey'],
                  -default  => [split /#/, $param{sports}])),
      p("Pick a city/state", scrolling_list(-name    => 'weather',
                                            -values  => \@citystate,
                                            -default => [split /#/, 
                                                         $param{weather}],
                                            -multiple => 1)),
      submit(-name => 'go', -value => 'Enter choices'),
      end_form;
}
elsif (param('go') eq 'Enter choices')
{
      $param{name}     = param('name');
      $param{sports}   = join("#", param('sports'));
      $param{weather}  = join("#". param('weather'));
      print start_form,
            p("Want to submit your choices? "),
            submit(-name => 'go', -value => 'yes'),
            submit(-name => 'go', -value => 'no'),
            end_form;
}      

print end_html;