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

I am receiving the message "Use of Uninitialized Value" at certain points when running my script. I have check all the variables and they are all set to the correct values. The program is outputting the correct stuff, but I am trying to clean up the code. Any ideas on the easiest way to debug this code? Here is the function I wrote:
sub gen_asp { my(@cmd) = (); my(@cmd1) = (); my($rs) = (); my($rs2) = (); my($submit) = $sec_homepage; $i = 0; $submit =~ tr |\\|/|; my(@keys) = keys %temp_dcr_hash; foreach $key (@keys){ if ("$temp_dcr_hash{$key}{LaunchDate2}" eq $today) { $home{$key} = $temp_dcr_hash{$key}; } # End of if statement } # End of foreach loop if ("(keys %home)" ne "" ){ foreach $key (@keys){ if("$temp_dcr_hash{$key}{LaunchDate2}" lt $today) { if ($key ne ""){ $cmd[0] = "copy $workarea\\$sec_homepage\\data\\$k +ey $archive\\$sec_homepage\\data\\$key"; $cmd[1] = "del /Q $workarea\\$sec_homepage +\\data\\$key"; $cmd[2] = "$cmd_path\\iwsubmit -w -u $vpat +h/$submit/data/$key \"Content Expired.\""; $cmd[3] = "$cmd_path\\iwsubmit -w -u $vpath_ar +c/$submit/data/$key \"Submitted to Staging.\""; } # End if statement for ($j=0; $j<4; $j++) { print "$cmd[$j]\n"; $rs = `$cmd[$j]`; print "$rs\n"; } # End for loop to run commands } # End if statement to check if the dcr is expired, arc +hive any that are and delete them from the site } # End foreach loop @home_sort = sort {$home{$b}{$modtime} <=> $home{$a}{$modtime} +} (keys %home); $outfile = "$workarea\\Index.asp"; $cmd1[0] = "$cmd_path\\iwpt_compile.ipl -pt $t_path\\home\\hom +e\\presentation\\home.tpl -iw_pt-dcr $t_path\\home\\home\\data\\$home +_sort[0] -ofile $outfile"; $cmd1[1] = "$cmd_path\\iwsubmit -w -u $outfile \"ASP Created.\ +""; for ($j=0; $j<2; $j++) { print "$cmd1[$j]\n"; $rs2 = `$cmd1[$j]`; print "$rs\n"; } # End for loop to run commands } # End if } #end sub
The issue arises in the command calls at the end, after cmd1[0] is run the error appears (a few times actually) and then the program completes the commands in the loop. Thanks, Bill

Replies are listed 'Best First'.
Re: Debugging "Use of Unitialized Value" message
by dragonchild (Archbishop) on Aug 27, 2001 at 20:57 UTC
    First off, are you using strict and warnings? It doesn't look like you are. strict will tell you if you've misspelled a variable name, by complaining that it wasn't declared.

    The second thing is to clean up your formatting! This sounds stupid, but how can you expect to have a clean-running program if your workspace (ie, your code) isn't neat and clean. I can barely read your code because there's random whitespace and logic isn't indented consistently. Indented consistently, your subroutine would look something like:

    sub gen_asp { my(@cmd) = (); my(@cmd1) = (); my($rs) = (); my($rs2) = (); my($submit) = $sec_homepage; $i = 0; $submit =~ tr |\\|/|; my(@keys) = keys %temp_dcr_hash; foreach $key (@keys){ if ("$temp_dcr_hash{$key}{LaunchDate2}" eq $today) { $home{$key} = $temp_dcr_hash{$key}; } # End of if statement } # End of foreach loop if ("(keys %home)" ne "" ){ foreach $key (@keys){ if("$temp_dcr_hash{$key}{LaunchDate2}" lt $today) { if ($key ne ""){ $cmd[0] = "copy $workarea\\$sec_homepage\\data\\$k +ey $archiv +e\\$sec_homepage\\data\\$key"; $cmd[1] = "del /Q $workarea\\$sec_homepage\\data\\ +$k +ey"; $cmd[2] = "$cmd_path\\iwsubmit -w -u $vpath/$submi +t/ +data/$key \"Content Expired.\""; $cmd[3] = "$cmd_path\\iwsubmit -w -u $vpath_arc/$s +ubmit/ +data/$key \"Submitted to Staging.\""; } # End if statement for ($j=0; $j<4; $j++) { print "$cmd[$j]\n"; $rs = `$cmd[$j]`; print "$rs\n"; } # End for loop to run commands } # End if statement to check if the dcr is expired, archive any # that are and delete them from the site } # End foreach loop @home_sort = sort {$home{$b}{$modtime} <=> $home{$a}{$modtime} +} (keys %home); $outfile = "$workarea\\Index.asp"; $cmd1[0] = "$cmd_path\\iwpt_compile.ipl -pt $t_path\\home\\hom +e\\present +ation\\home.tpl -iw_pt-dcr $t_path\\home\\home\\data\\$home_sort[0] - +ofile $outf +ile"; $cmd1[1] = "$cmd_path\\iwsubmit -w -u $outfile \"ASP Created.\ +""; for my $j (0 .. 2) { print "$cmd1[$j]\n"; $rs2 = `$cmd1[$j]`; print "$rs\n"; } # End for loop to run commands } # End if } #end sub

    ------
    /me wants to be the brightest bulb in the chandelier!

    Vote paco for President!

Re: Debugging "Use of Unitialized Value" message
by guillaume (Pilgrim) on Aug 27, 2001 at 21:00 UTC
    The "use of uninitialized value" error arise when you use a variable that hasn't been defined before.

    As for debugging your code, make sure you put
    use warnings; use strict;
    at the beginning of your script. Also, when asking for help make sure you reduce your code to a minimum (try to post only the part of the code causing the errors), and giving the exact errors messages would help too.

    Other than that, to debug you could add more "or die" statements and sprinkle your code with "print" statements outputting the value of your variables to make sure they contains what you think they contains.

    Guillaume
Re: Debugging "Use of Unitialized Value" message
by Jazz (Curate) on Aug 27, 2001 at 21:50 UTC
    It looks like you set $i = 0 earlier, but use $j in your loops. This may be the culprit because you noted that the warnings appear around your cmd lines.

    If you used -w, you would have seen that $i was used only once; possible typo. Was it?

    I definitely agree with the previous 2 posts: -w and strict should always be used and formatting should be consistent. Jasmine

Re: Debugging "Use of Unitialized Value" message
by jryan (Vicar) on Aug 27, 2001 at 21:50 UTC

    I think this might be your problem:

    $cmd[0] = "copy $workarea\\$sec_homepage\\data\\$key $archive\\$sec_ho +mepage\\data\\$key"; $cmd[1] = "del /Q $workarea\\$sec_homepage\\data\\$key"; $cmd[2] = "$cmd_path\\iwsubmit -w -u $vpath/$submit/data/$key \"Conten +t Expired.\""; $cmd[3] = "$cmd_path\\iwsubmit -w -u $vpath_arc/$submit/data/$key \"Su +bmitted to Staging.\"";

    None of those variables are passed to the sub, or created in the sub. Therefore, they are unitialized. I think what you mean to do is store those names in the @cmd array. To do that, the $ need to be backslashed.

    $cmd[0] = "copy \$workarea\\\$sec_homepage\\data\\$key $archive\\\$sec +_homepage\\data\\$key"; $cmd[1] = "del /Q\$workarea\\\$sec_homepage\\data\\$key"; $cmd[2] = "\$cmd_path\\iwsubmit -w -u \$vpath/\$submit/data/$key \"Con +tent Expired.\""; $cmd[3] = "\$cmd_path\\iwsubmit -w -u \$vpath_arc/\$submit/data/$key \ +"Submitted to Staging.\"";

    If that isn't it, please tell us what your function is supposed to do :)

      I think you're mistaken. wstarrs is probably using a number of global variables set outside of the function. Those variable names probably shouldn't be backslashed. *winces* That's probably part of his problem, too.

      ------
      /me wants to be the brightest bulb in the chandelier!

      Vote paco for President!