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

Dear monks, beginning Perl user here. The following code is an excerpt from a larger script taken from a book called Baseball Hacks, published a few years ago. The author's scripts do not 'use strict' and so I tried to go through the script and make the necessary changes. One section of code which interacts with the Time::Local module has been giving me problems. Specifically, when I try to change the variable ($t) to 'my $t' or $start to 'my $start' the script runs without error except that the processing date then becomes 12/31/1969 instead of what I currently have intended which is 8/16/07. Any idea as to why this might be happening?
use Strict; use Warnings; use Time::Local; # subroutine extracts and formats date from a time stamp sub extractDate($) { # extracts and formats date from a time stamp ($t) = @_; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($t); $mon += 1; $year += 1900; $mon = (length($mon) == 1) ? "0$mon" : $mon; $mday = (length($mday) == 1) ? "0$mday" : $mday; return ($mon, $mday, $year); } # get all data from website from 8/16/07 to present my $start = timelocal(0,0,0,16,7,107); ($mon, $mday, $year) = extractDate($start); print "starting at $mon/$mday/$year\n"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); my $now = timelocal(0,0,0,$mday - 0,$mon,$year); #$now = timelocal(0,0,0,$mday - 1,$mon,$year); #$now = timelocal(0,0,0,3,10,105); ($mon, $mday, $year) = extractDate($now); print "ending at $mon/$mday/$year\n"; for ($t = $start; $t < $now; $t += 60*60*24) { ($mon, $mday, $year) = extractDate($t); print "processing $mon/$mday/$year\n";

Replies are listed 'Best First'.
Re: 'Use Strict' conflicts with Time::Local module
by ikegami (Patriarch) on Aug 22, 2007 at 20:45 UTC

    The modules are called strict and warnings, and I cannot reproduce your problem. Could you actually show the code that gives the error?

    By the way, the underlying logic of your program is buggy. It made the mistake of assuming every day has 24*60*60 seconds. You should be using Date::Calc to do date arithmetic.

Re: 'Use Strict' conflicts with Time::Local module
by Roy Johnson (Monsignor) on Aug 22, 2007 at 20:49 UTC
    You're probably re-declaring a variable. Here's my edit of the code, which runs cleanly and correctly:
    use strict; use warnings; use Time::Local; # subroutine extracts and formats date from a time stamp sub extractDate($) { # extracts and formats date from a time stamp my ($t) = @_; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($t); $mon += 1; $year += 1900; $mon = (length($mon) == 1) ? "0$mon" : $mon; $mday = (length($mday) == 1) ? "0$mday" : $mday; return ($mon, $mday, $year); } # get all data from website from 8/16/07 to present my $start = timelocal(0,0,0,16,7,107); my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst); ($mon, $mday, $year) = extractDate($start); print "starting at $mon/$mday/$year\n"; ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time +); my $now = timelocal(0,0,0,$mday - 0,$mon,$year); #$now = timelocal(0,0,0,$mday - 1,$mon,$year); #$now = timelocal(0,0,0,3,10,105); ($mon, $mday, $year) = extractDate($now); print "ending at $mon/$mday/$year\n"; my ($t); for ($t = $start; $t < $now; $t += 60*60*24) { ($mon, $mday, $year) = extractDate($t); print "processing $mon/$mday/$year\n"; }

    Caution: Contents may have been coded under pressure.
      Thanks for the help. I was able to input Roy Johnson's edited code in and it worked like a charm. I'm pretty sure you hit it right on in that I wasn't correctly declaring variables. One thing that I know I did not do before was put in the extra declaration, "my ($t);" near the bottom of the code. I'm guessing that there is a more efficient way to run the process; understanding the alternatives will come with time.
Re: 'Use Strict' conflicts with Time::Local module
by FunkyMonk (Bishop) on Aug 22, 2007 at 21:22 UTC
    use Strict;
    use Warnings;
    Just a word of warning. This code may not compile in the upcoming 5.10 release of Perl. It just depends how loudly perl complains.

    From perl595delta:

    Module changes
    [...]
    "strict" and "warnings"

    "strict" and "warnings" will now complain loudly if they are loaded via incorrect casing (as in "use Strict;"). (Johan Vromans)

Re: 'Use Strict' conflicts with Time::Local module
by dwm042 (Priest) on Aug 22, 2007 at 21:06 UTC
    Well, for one, @_ is in array context, so one appropriate way to fetch $t and use $t in the subroutine extractDate is:

    my ($t) = @_;
    or you could use

    my $t = shift;
    If you add the code

    print "t = $t\n";
    below your original $t assignment in your function, it returns the value 1.

    This shows that the net effect of

    my $t = @_;
    is
    my $t = scalar @_;
    Instead of a time, you're getting the total number of elements in the array @_.

    Update: added comments about array to scalar assignment.