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

Dear Monks,

This is a beginner CGI question. I'm trying to create a form that reads in existing CGI objects from a file into a hash that will later be used to populate textfields with default values. I read in the objects with:

my $roster_entry; my %roster_entries; while (!eof(ROSTER_FH)) { $roster_entry = CGI->new(\*ROSTER_FH); my $full_name = $roster_entry->param('last_name') . "," . $roster_ +entry->param('first_name'); $roster_entry->param('full_name', $full_name); $roster_entries{$full_name} = $roster_entry; }

If the form has not been filled out, the user is asked to select a name from a popup-menu. Once this has been done, the user is presented with textfields populated with the values from the above array. (Note that for simplicity, I have just used print statements below rather than the textfields.)

my $query = CGI->new(); if ($query->param('full_name')) { my $full_name = $query->param('full_name'); print p("<br>\$full_name = $full_name\n<br>"); print p("<br>\$roster_entries{$full_name}->param('address') = $ros +ter_entries{$full_name}->param('address')\n<br>"); } else { # Display dropdown box with names print p("In order to update your contact information, select your +name below and click the Submit button\n"); print start_form; print p($query->popup_menu( -name=>'full_name', -values=>[sort keys %roster_entries] )); print p(submit("Submit")); print end_form, end_html; }
The problem is that in the if statement, $roster_entries{$full_name} does not dereference the way I expect. The output I get is:
$full_name = Last1, First1 $roster_entries{Last1, First1}->param('address') = ->param('address')
when I would expect to see:
$full_name = Last1, First1 $roster_entries{Last1, First1}->param('address') = 111 First Street
My full code is below:
#!c:/perl/bin/perl.exe use strict; use warnings; use CGI qw(:standard); use Fcntl qw(:flock); my $ROSTER_CGI_FILE = "c:/temp/test_roster.txt"; print header, start_html(), h2(); # This is for the page that displays + in the browser #### Getting existing roster data open(ROSTER_FH, "+< $ROSTER_CGI_FILE") or bail("Cannot open $ROSTER_CG +I_FILE: $!"); flock(ROSTER_FH, LOCK_EX) or bail("Cannot flock $ROSTER_CGI_FILE: $!") +; my $roster_entry; my %roster_entries; # Creating an array of roster objects from existing list while (!eof(ROSTER_FH)) { $roster_entry = CGI->new(\*ROSTER_FH); my $full_name = $roster_entry->param('last_name') . ", " . $roster +_entry->param('first_name'); $roster_entry->param('full_name', $full_name); $roster_entries{$full_name} = $roster_entry; } ### Starting the update process my $query = CGI->new(); if ($query->param('full_name')) { # If user has chosen a name from the + dropdown box, then provide additional dropdown boxes already filled +in with current information my $full_name = $query->param('full_name'); print p("<br>\$full_name = $full_name\n<br>"); print p("<br>\$roster_entries{$full_name}->param('address') = $ros +ter_entries{$full_name}->param('address')\n<br>"); print p("<b>Updating entry for:</b> ", $full_name, "\n<br>"); print start_form; print p("Street Address: ", $query->textfield(-NAME => "address", +-VALUE => "$roster_entries{$full_name}->param('address')", -SIZE => 5 +0, -maxlength=>50)); print("City: ", $query->textfield(-NAME => "city", -VALUE => "$ros +ter_entries{$full_name}->param('city')", -SIZE => 20, -maxlength=>20) +); print("&nbsp;&nbsp;State: ", $query->textfield(-NAME => "state", - +VALUE => "$roster_entries{$full_name}->param('state')", -SIZE => 2, - +maxlength=>2)); print("&nbsp;&nbsp;Zip: ", $query->textfield(-NAME => "zip", -VALU +E => "$roster_entries{$full_name}->param('zip')", -SIZE => 7, -maxlen +gth=>7)); print p("Home phone: ", $query->textfield(-NAME => "home_phone", - +VALUE => "$roster_entries{$full_name}->param('home_phone')", -SIZE => + 12, -maxlength=>12)); print p("Cell phone: ", $query->textfield(-NAME => "cell_phone", - +VALUE => "$roster_entries{$full_name}->param('cell_phone')", -SIZE => + 12, -maxlength=>12)); print p("Email: ", $query->textfield(-NAME => "email", -VALUE => " +$roster_entries{$full_name}->param('email')", -SIZE => 30, -maxlength +=>30)); print p(submit("send"), defaults("clear")); print end_form, end_html; } else { # Display dropdown box with names print p("In order to update your contact information, select your +name below and click the Submit button\n"); print start_form; print p($query->popup_menu( -name=>'full_name', -values=>[sort key +s %roster_entries] )); print p(submit("Submit")); print end_form, end_html; } close(ROSTER_FH); ################################################## # # Subroutines # ################################################## sub bail { my $error = "@_"; print h1("Unexpected error"), p($error), end_html; die $error; }
I’m guessing my mistake is simple, but I don’t see it. Any help would be appreciated.


Thank you,
memnoch

Replies are listed 'Best First'.
Re: Trouble dereferencing CGI objects
by merlyn (Sage) on Dec 27, 2007 at 20:29 UTC
    " ... $roster_entries{$full_name}->param('address') ... "
    You can't interpolate a method call arrow, only dereferencing arrows.

    If you want to perform a method arrow (like param), you'll need to do it outside the quotes:

    print "some stuff here ", $roster_entries{$full_name}->param('address' +), " and more stuff here";
Re: Trouble dereferencing CGI objects
by bradcathey (Prior) on Dec 27, 2007 at 20:36 UTC

    Nice foundational work, but the sooner you look into HTML::Template and HTML::FillInForm the better. You will be stunned by how much easier this kind of routine stuff gets handled.


    —Brad
    "The important work of moving the world forward does not wait to be done by perfect men." George Eliot