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

I'd like to streamline an already simple CGI script using foreach or while and a hash of URL's.

The example below shows what works, as well as how it *doesn't* work when placed inside a CGI.pm HTML table.   I've read TPJ's Coping with Scoping plus perldoc CGI.pm, but am just not getting it.

Direction or sample code greatly appreciated.
    cheers,
    ybiC

#!/usr/bin/perl -wT use strict; use CGI::Carp qw (fatalsToBrowser); use CGI::Pretty qw(:all); my %urlhash = ('Perl Monks' => "http://www.perlmonks.org/", 'Debian' => "http://www.debian.org/", 'OpenBSD' => "http://openbsd.org/", ); print header(-type => 'text/html', -expires => 'now'), start_html (-title => 'hash.cgi'); # FOREACH & WHILE SYNTAX WORKS FINE HERE #print "<p> ==HASH FOREACH=="; #foreach my $key (keys %urlhash) { # print "<br>", a({href => "$urlhash{$key}"}, "$key"), # } #print "<p> ==HASH WHILE=="; #while((my $key, my $value) = each(%urlhash)) { # print "<br>", a({href => "$urlhash{$key}"}, "$key"), # } print table, (Tr, (td, ( # BUT NEITHER WORKS FROM INSIDE CGI.PM TABLE. # 'syntax error at line 29, near "foreach"' foreach $main::key (keys %urlhash) { print "<br>", a({href => "$urlhash{$key}"}, "$key"), } # 'syntax error at line 34, near "while"' while(($main::key, $main::value) = each(%urlhash)) { print "<br>", a({href => "$urlhash{$key}"}, "$key"), } ), ), ); # close td, Tr, table print end_html;

Replies are listed 'Best First'.
Re: while, foreach inside CGI.pm table
by merlyn (Sage) on Aug 15, 2000 at 22:21 UTC
    There's a couple of solutions.
    • Rewrite all your foreach as "map", which is a "process this input to get that output" operator, exactly what you need here:
      print Table(Tr(td( map { a({href => $urlhash{$_}}, $_), br } sort keys %urlhash )));
    • Use the optional "start/end tag" generators:
      use CGI qw(:all *table *Tr *td); print start_table, start_Tr, start_td; for (sort keys %urlhash) { print a({href => $urlhash{$_}}, $_), br; } print end_td, end_Tr, end_table;
    Your choice.

    -- Randal L. Schwartz, Perl hacker

Re: while, foreach inside CGI.pm table
by btrott (Parson) on Aug 15, 2000 at 22:20 UTC
    You can't execute arbitrary code while invoking a subroutine like that. You need to pass a string to the CGI.pm method, and it'll wrap it in a table.

    I think this should work for you:

    print table(Tr([ td( join "<br>\n", map { a({href => $urlhash{$_}}, $_) } keys %urlhash ) ]));
RE: while, foreach inside CGI.pm table (thank you)
by ybiC (Prior) on Aug 16, 2000 at 06:38 UTC
    Once again, I find myself thanking Wiser Monks Than I(TM) for sharing their expertise.   This time around it's jcwren, btrott, and merlyn, who gave timely, informative, understandable, and practical answers.

    Sometime in the next week or so, I'll update my recent (humble) Code Catacombs entry with changes gleaned from their advice.
        cheers,
        ybiC