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

Being completely new to the CGI field, my school had hired me (for free) to write a block rotation script for out school webpage, for the coming semester. I've written some code to make this work. My problem lies in having my code print out from the server it is on.
With command prompt, I can easily and effectively run my program, and it shows up as if nothin was wrong with it.
The problem arises when I try to get it to print out on my webpage.
I have a hash called %blocks and i call upon it by printing out $block{$day} $day being the day of the year it is (between 0..364).
Same goes for my array @event. Is the reason these variable are not producing anything the fact that they:

  1. They are defined in the subroutine?
  2. or is there something special with Hashes and Arrays in CGI?
#!/usr/bin/perl -w use strict; use CGI qw(:standard); my (%blocks, $date, $timeholder, $block, @timeholder, @event); get_block(); print header(), start_html("Block Order Script"), h1("The Next Block O +rder is: "); my @timer = localtime(time); my $day = $timer[7]; my $hour=$timer[2]; my $minute= $timer[1]; my $dotw =$timer[6]; if (($hour >= "14") && ($minute > "11") && ($dotw != "1") && ($dotw != + "7")) { $day++; }elsif ($dotw == "1"){ $day++; } elsif (($hour >= "14") && ($minute >"11") && ($dotw == "6")){ $day+=3; } elsif($dotw == "7") { $day+=2; } print p($blocks{$day}); print p($event[$day]); print end_html; sub get_block { open (BLOCK, "/home/signguy/public_html/DB_Files/block.db") or die "$! +"; my $r = 0; while ($date = <BLOCK>) { chomp ($date); $block = <BLOCK>; chomp ($block); $event[$r] = <BLOCK>; chomp ($event[$r]); $blocks{$date} = ($block); $r++; } close (BLOCK); }

----------------------------
Wiz, The VooDoo Doll
Head Master of 12:30 Productions
----------------------------

Replies are listed 'Best First'.
(jeffa) Re: Hash and Array Printouts in CGI
by jeffa (Bishop) on Jul 13, 2001 at 03:13 UTC
    Eek! Global variable are trouble if you don't use them properly. I recommend that sub get_block return your data structures via references:
    sub get_block { my (%blocks,@events); # rest of code return (\%blocks,\@events); } # and call it like so my ($blocks_ref,$events_ref) = get_block(); print p($blocks_ref->{$day}); print p($events_ref->[$day]);
    Untested, i hope this solves your problem.

    Jeff

    R-R-R--R-R-R--R-R-R--R-R-R--R-R-R--
    L-L--L-L--L-L--L-L--L-L--L-L--L-L--
    
Re: Hash and Array Printouts in CGI
by CheeseLord (Deacon) on Jul 13, 2001 at 05:11 UTC

    Okay, I redid your script, and I think I got your intentions right. Let me know if I got it wrong.

    #!/usr/bin/perl -w use strict; use CGI qw(:standard); my ($block_ref, $event_ref) = get_block(); print header(), start_html("Block Order Script"), h1("The Next Block Order is: "); my ($hour, $min, $day, $dotw) = (localtime)[2, 1, 7, 6]; my $time = sprintf "%02d%02d", $hour, $min; # Comments explained: (U M T W R F S) maps to (Sun Mon ... Sat) # If it's MTWR, and past 2:11pm, display tomorrow. if ((grep {$dotw == $_} (1, 2, 3, 4)) && $time > 1411) { $day++ } # If it's SU, display M. elsif (grep {$dotw == $_} (6, 0)) { my $adj = $dotw / 6 + 1; $day += $adj; } # If it's F, and past 2:11pm, display M. elsif ($dotw == 5 && $time > 1411) { $day += 3 } print p($block_ref->[$day]); print p($event_ref->[$day]); print end_html; sub get_block { my (@blocks, @events); open (BLOCK, "block.db") or die "$!"; while (my $date = <BLOCK>) { chomp ($date); chomp ($blocks[$date] = <BLOCK>); chomp ($events[$date] = <BLOCK>); } close (BLOCK); return (\@blocks, \@events); }

    Note: This is very poorly tested -- Try using it on different times first -- I've only checked it for today.

    His Royal Cheeziness

Re: Hash and Array Printouts in CGI
by wiz (Scribe) on Jul 13, 2001 at 03:53 UTC
    With edits:
    #!/usr/bin/perl -w use strict; use CGI qw(:standard); my (%blocks, $date, $timeholder, $block, @timeholder); print header(), start_html("Block Order Script"), h1("The Next Block O +rder is: "); my @timer = localtime(time); my $day = $timer[7]; my $hour=$timer[2]; my $minute= $timer[1]; my $dotw =$timer[6]; if (((($hour == "14") and ($minute >="11")) || ($hour>= "15")) and ($d +otw != "0") and ($dotw != "6")) { $day++; }elsif ($dotw == "0"){ $day++; } elsif (((($hour >= "14") and ($minute >"11")) || ($hour>= "15")) and + ($dotw == "5")){ $day+=3; } elsif($dotw == "0") { $day+=2; } my ($blocks_ref,$events_ref) = get_block(); print p($blocks_ref->{$day}); print p($events_ref->[$day]); print end_html; sub get_block { my (%blocks,@event, $date); open (BLOCK, "/home/signguy/public_html/DB_Files/block.db") or die "$! +"; my $r = 0; while ($date = <BLOCK>) { chomp ($date); $block = <BLOCK>; chomp ($block); $event[$date] = <BLOCK>; chomp ($event[$date]); $blocks{$date} = ($block); $r++; } return (\%blocks,\@event); }

    I'm running the script here and I'm running this DB file

    ---------------------------- Wiz, The VooDoo Doll Head Master of 12:30 Productions ----------------------------
      With the version now up, you can eliminate the $r index variable.
Re: Hash and Array Printouts in CGI
by petral (Curate) on Jul 13, 2001 at 03:32 UTC
    As mentioned in the cb $dotw is between 0 and 6.
    And, of course, 3:05 p.m. is after 2:11 p.m. but $hour >= 14 and $minute >= 11 is false.

      p

Re: Hash and Array Printouts in CGI
by HyperZonk (Friar) on Jul 13, 2001 at 03:42 UTC
    As noted in chatterbox, $r variable in get_block will unsync with day numbers if one day is missing in block.db; consider using $date as the index directly. Also, $r increments at the end of the sub, so if the db day number begins at day 1, then $r is not synced to begin with.
Re: Hash and Array Printouts in CGI
by wiz (Scribe) on Jul 13, 2001 at 03:25 UTC
    The format of block.db is:

    NumberofDateOutofYear<br> Block Listing<br> Any special events.<br>


    ---------------------------- Wiz, The VooDoo Doll Head Master of 12:30 Productions ----------------------------