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

I'm sure I'm missing something obvious, but for some reason my script seems to just hang near the end (WinXP, Activestate 5.8), even when I use die to try to kill it (it doesn't go back to the command prompt).

The script did exit earlier in its development, so I don't think it's the modules (although I did notice some interesting warnings being generated from the Spreadsheet::BasicRead module). If anyone can see anything structurally or syntactically (or otherwise) doing wrong, let me know. . . thank you. . .
Essentially, the idea is to pull down a publicly available spreadsheet, read some values in it, sum them, compare the sum to a value in the database, and then send an email if the values differ (eventually I may just do the update, but I want to run it awhile first).
#!perl use LWP::Simple; use LWP::UserAgent; use Mail::Sender; use DBI; use Spreadsheet::BasicRead; ($user, $pwd, $email) = @ARGV; $date = time(); ($sec, $min, $hour, $day, $mon, $year) = localtime $date; $curryear = $year + 1900; $xmon = sprintf ("%02d", $mon+1); $day = sprintf ("%02d", $day); $year =~ /\d\d(\d\d)/; $truncyear = $1; $name = "C:/sp500-".$xmon.$day.$truncyear.".xls"; &GetSNPfile($name); $spread = new Spreadsheet::BasicRead($name) || die "Error: $!"; print "Opened Spread...\n"; while ($data = $spread->getNextRow()){ last if ($$data[0] eq "ACTUALS"); next if !($$data[0] =~ m,/\d+/,); $$data[0] =~ m,/\d{2}/(\d{4}),; $year = $1; push @ests, $$data[2]; } print join "\t", @ests; @fwd_four = (reverse @ests)[0..3]; for (@fwd_four){$sum+=$_;} print "\n".$sum."\n"; $dbh = DBI->connect('dbi:Oracle:host=oraclehost;sid=dbsid', $user, $pwd, { RaiseError => 1, PrintError => 1 } ); $getsnp = $dbh->prepare("Select COLUMN from TABLE where ANOTHERCOLUMN += ?"); $getsnp->execute($curryear + 1); @row = $getsnp->fetchrow_array; ($snp_eps)=@row; if($snp_eps != $sum){ $result = "Different values!\nDB:\t$snp_eps \nWEB:\t$sum"; } else{ $result = "Same values. . . \nDB:\t$snp_eps \nWEB:\t$sum"; } print $result; $sender = new Mail::Sender {smtp => 'mail.mailhost.com', from => 'scg@mailhost.com'}; $sender->MailMsg({to => $email, subject => "Message", msg => $result}); die "silly program doesn't know it's over"; sub GetSNPfile{ ($get) = @_; print "Getting SNP file from web. . . \n"; $snp = getstore("http://www2.standardandpoors.com/spf/xls/index/SP500E +PSEST.XLS", $get); print "Done getting file. . . \n"; $snp; }

Replies are listed 'Best First'.
Re: Script no longer exiting
by graff (Chancellor) on Oct 16, 2004 at 05:22 UTC
    ...even when I use die to try to kill it...

    So, it must be hanging before it reaches the "silly" die statement. Do you see the output of  print $result; and does the email from the Mail::Sender call get delivered? Is the spreadsheet file that you're fetching in GetSNPfile being saved to local disk, and is it readable by another application (e.g. Excel(tm))?

    Just for grins, try "use strict" (it's not that hard in this case), then try enclosing the DBI and Mail::Sender stuff inside their own blocks (or each in its own sub, like you've done with the LWP part), so that the objects will go out of scope and connections will be closed if/when you leave the block or sub.

    You could also try stepping through it with the perl debugger, to see what it is trying to execute when it hangs. (You can even step into a given module call, if you establish that it's not returning from there.) As you step along, check the values of variables that are about to be passed to a module, to make sure they contain what you intend/expect.

Re: Script no longer exiting
by Roger (Parson) on Oct 16, 2004 at 11:57 UTC
    even when I use die to try to kill it

    Well, most likely your code never gets to the die function. Please state what exactly your code prints out, that may give us more clue as which statement caused the script to hang. I have made a guesses nevertheless: the while loop never exists and the execution never reaches the die function.

    Another comment I want to make regarding your code is to use strict and use warnings. Have strict variable declarations to prevent Perl from automatically create variables for you. This will make your code easier to trace, and may save you a lot of debugging time in the future. One of the most comment dangers of not using strict pragma in the code is to misspell a variable name, and Perl creates a new variable with the misspelt name, leaving an inexperienced coder hours to figure out what is wrong with the code.

      Thanks for the advice, I certainly will do that (I hope to get to it later today). I'm not really sure how to run perl in the debugger. I apologize for not including the output or being more explicit in my original post.

      The output is:
      c:\WINDOWS>snp500eps xxx xxx scg@mailhost.com Getting SNP file from web. . . Done getting file. . . Opened Spread... 19.24 18.52 18.13 16.97 17.24 16.31 68.65 Different values! DB: 68.07 silly program doesn't know it's over at C:\Perl\bin\snp500eps.pl line +63. WEB: 68.65

      where it just hangs with a blinking cursor at the end of "68.65_" (the underscore is the cursor). It does get the spreadsheet, the spreadsheet can be opened and the values get printed out appropriately, and the email is sent (so I know the variables' values are fine, and it certainly appear that it does actually get to the die function).

      Typically, I do use warnings, one reason I didn't here is because I notice a warning coming out of BasicRead related to a pack statement (this doesn't seem to interfere with actually reading the spreadsheet, however).
        Looks suspicious, smells like some sort of text input problem. Can you try to append "\n" to the end of the $result, and see what happens?