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

I have a cgi name and address application which is mainly working. I am however having trouble retrieving an array of objects.

---abstracted from first screen (working)

my @phn = Phones->load($pcode); Phones->show_all; print $q->hidden("hide_phone", @phn);
--second screen retreives data
Phones->get_param;
included are the returns from the warn on line 934 936, the first time line 937 is commented.
NA.cgi: Phones=HASH(0x84f7f90) at /usr/local/cgi-bin/NA.cgi line 934.
NA.cgi: Phones=HASH(0x84f7f90) at /usr/local/cgi-bin/NA.cgi line 936.
Phones=HASH(0x84f8020) at /usr/local/cgi-bin/NA.cgi line 934.
NA.cgi: Phones=HASH(0x84f8020) at /usr/local/cgi-bin/NA.cgi line 936.
NA.cgi: Phones=HASH(0x84f8a5c) at /usr/local/cgi-bin/NA.cgi line 934.
NA.cgi: Phones=HASH(0x84f8a5c) at /usr/local/cgi-bin/NA.cgi line 936.
when uncommented 937 however fails trying to access the Phones objects, how do get acces to my data?
Can't use string ("Phones=HASH(0x84f7f90)") as a HASH ref while
     "strict refs" in use at /usr/local/cgi-bin/NA.cgi line 937.
package Phones; my @phones; sub load {i -- Loads phone types and phone numbers for one individual +from DB my ($o,$pcode) = @_; my $sel = "select pcode, typephone, phonenumber from phones where +pcode = $pcode"; my $ph = main::do_sql ($sel); my @phone; while (my @fld = $ph->fetchrow_array( ) ) { $fld[1] = $fld[1] || 'H'; push(@phone, \@fld); } my @dummy = ($pcode,'H',''); push(@phone, \@dummy); foreach(@phone){ $obj = new($_); push (@phones, $obj); $obj->trace; } return @phones; } sub new{ my (@d) = @_; my $Phone ={ "pid" => $d[0][0], "o_typ" => $d[0][1], "o_phn" => $d[0][2], "n_typ" => $d[0][1], "n_phn" => $d[0][2], "trc" => 'new', }; bless $Phone, 'Phones'; return $Phone; #return object reference } sub get_param{ my @phn = $q->param("hide_phone"); my $a; foreach $a (@phn){ foreach($a){ foreach $obj ($_){ warn "$obj"; ----------line 934 ------------- foreach ($obj){ warn $_; ----- line 936 warn "$_->{'n_typ'}"; ## $_->trace; } } } } } sub show{ my ($r) = $_[0]; my $phn = $r->{'o_phn'}; my $name = $r->{'o_phn'} || $r->{'pid'}; my $typ = "T$name"; my $def = PhoneTypes->translate($r->{'o_typ'}); my @val = split(':',PhoneTypes->list); $r->{'trc'} = "show->name=$typ"; $r->trace; print $q->popup_menu( -name=>$typ, -values=> \@val, -default=>$def); print $q->textfield( -name=>$name, -default=> $phn); print $q->p; } sub show_all{ foreach(@phones){ $_->show; } }

Replies are listed 'Best First'.
(jeffa) Re: CGI hidden retreive array
by jeffa (Bishop) on Jun 10, 2003 at 14:46 UTC
    This code needs comments ... bad! Trying to understand what is going is too much to ask someone without detailed explanation of why you made this sooo complicated. If i had to guess ... and i have to, change line 937 from this:
    warn "$_->{'n_typ'}";
    to this:
    warn $_{'n_typ'};
    Because if i am guessing correctly, $_ in this context is not a hash reference, but the hash itself. If this is not the problem, then just wait - hopefully someone else with more free time on their hands will be spot your error. In the meantime, think about design - code this complex needs it. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
Re: CGI hidden retreive array
by benn (Vicar) on Jun 10, 2003 at 14:53 UTC
    Your main problem is that you're *printing* @phn (in your hidden field) and then reading back its string representation - as your error message says, it can't use string "Phones=HASH(0x84f7f90)" as a hashref. Indeed, that hashref doesn't exist any more.

    If you want to pass data from invocation to invocation, you'll need to either pass all data as strings (phones[$i]->{pcode} etc.) or save it all somewhere else, in a session db for instance, or by simply passing user-ids around and re-reading your db each time.

    Cheers, Ben.

Re: CGI hidden retreive array
by davorg (Chancellor) on Jun 10, 2003 at 14:55 UTC

    This code is very hard to follow. It would have been nice if you had given us a cut-down version of the program to work with.

    Basically, it looks like you are writing <hidden> fields that contain objects. These are therefore converted from references to strings, so when you try to read them and use them as objects Perl doesn't know what to do with them.

    You should only every use scalars containing text or numbers as the value on an HTML form field.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

Re: CGI hidden retreive array
by Jenda (Abbot) on Jun 10, 2003 at 15:35 UTC

    The hidden field may only store a STRING, not a whole data structure. So you have to serialize that datastructure (convert to a string containing all the data) first and deserialize it (construct and initialize the datastructure and objects) later. You might try to use Storable or Freeze::Thaw or serialize and deserialize yourself.

    Jenda
    Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
       -- Rick Osborne

    Edit by castaway: Closed small tag in signature