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

NOW IT WORKS, I must have fat-fingered the previous 300 times. Please disregard.
Esteemed (and steamy) monks, I'm trying to dereference a hash to build a link. I've run a query and am looping thru an array of arrays to build a table. On the third column I want to insert the link - using the contents of that column @$_[1] to derefernce the value from the hash $real_hash->{@$_[0]}, but I get no data. I'm wondering if behind the scenes I'm overwriting some built-in variable. Thanks in advance for your help. Code follows ---------------
sub makeTable { my ($ref, $cols) = @_; my $one_col = ""; #pull in ref. to hash (doc. name, URL) my $links_ref = ($cols =~ /MPS/) ? &getMPSlinks : ""; #----make column titles, and begin html code for table my @cols = split (/,/,$cols); foreach (@cols) {$labels .= qq|<td>$_</td>|;} my $table = qq|<table class="center"><tr class="table_labels">$lab +els</tr>|; foreach (@$ref) { #loop thru array of arrays, inside we'll take ea +ch array and break out into table $table .= ++$count % 2 == 1 ? qq|<tr class="row_light">| : qq|< +tr class="row_dark">|; #alaternate row colors #---Build tables here------------------------------------------ +----- if ($form{"query"} eq "deptcodes") { my $doc_num = qq|@$_[2]|; #PROBLEM CHILD ON NEXT LINE $table .= qq|<td>@$_[0]</td><td>@$_[1]</td><td><a href="$ +links_ref->{@$_[0]}" target="_blank">@$_[2]</a></td>|; + } } $table .= "</table>"; return($table); } #this returns a ref to a hash. key is doc. name, value is URL sub getMPSlinks { our %mps_hash=(); my ($one_mps, $one_url) = ""; open(HANDLE, "< $cgi_path/mpslinks.txt") or die "***Couldn't +open $path for reading: $!\n"; while (<HANDLE>) { ($one_mps, $one_url) = split (/\|/,$_); $mps_hash{$one_mps} = "$one_url"; #print "<strong>$one_mps</strong><br> $one_url"; } close (HANDLE); return (\%mps_hash); }

Replies are listed 'Best First'.
Re: trouble dereferencing a hash reference
by bobf (Monsignor) on Mar 21, 2006 at 18:15 UTC

    Welcome to the Monastery! Congratulations on solving the problem, and thanks for updating the OP accordingly.

    I couldn't help but notice the subroutine in your code that generates a table in HTML. While this may work, it is usually a better idea to separate the logic code from the display so you can more easily change one without having to worry about the other. In this case, I'd recommend using an HTML templating module, such as HTML::Template. There is a very small learning curve, and once you try it you'll be hooked. :-)

    Here is a quick example. I put the template in a separate file, but you can just as easily keep it in the same file as the rest of your code (see the docs). You can print the resulting HTML directly to a file or you can store it in another variable (and return it from a subroutine, as in your case).

    use strict; use warnings; use HTML::Template; my $template = HTML::Template->new( filename => 'html_template.tmpl' ) +; # set the VAR1 parameter $template->param( VAR1 => 'this is var 1' ); # create data for the table and set TESTLOOP my @loopdata; for( 0 .. 3 ) { push( @loopdata, { cell1 => "row $_ cell 1", cell2 => "row $_ cell 2" } ); } $template->param( TESTLOOP => \@loopdata ); # print to output file open( my $outfh, '>', 'html_template_output.html' ) or die "error opening output file:\n$!"; print $outfh $template->output(); close $outfh; # get output as a string of HTML my $output = $template->output(); print $output;

    Here is the template file:

    <html> <head> <title>This is a test template for HTML::Template</title> </head> <body> Var1 = <TMPL_VAR NAME=VAR1> <br> Loop: <br> <table> <TMPL_LOOP NAME=TESTLOOP> <tr> <td>Cell 1 = <TMPL_VAR NAME=CELL1></td> <td>Cell 2 = <TMPL_VAR NAME=CELL2></td> </tr> </TMPL_LOOP> </table> </body> </html>

    And the output:

    <html> <head> <title>This is a test template for HTML::Template</title> </head> <body> Var1 = this is var 1 <br> Loop: <br> <table> <tr> <td>Cell 1 = row 0 cell 1</td> <td>Cell 2 = row 0 cell 2</td> </tr> <tr> <td>Cell 1 = row 1 cell 1</td> <td>Cell 2 = row 1 cell 2</td> </tr> <tr> <td>Cell 1 = row 2 cell 1</td> <td>Cell 2 = row 2 cell 2</td> </tr> <tr> <td>Cell 1 = row 3 cell 1</td> <td>Cell 2 = row 3 cell 2</td> </tr> </table> </body> </html>

    I hope this helps. There is a lot of information around here (and CPAN) on templating. Super Search is your friend. :-)