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

Greetings fellow monks. I have a perl/CGI script which is behaving rather badly. From the apache logs, I get the following when the script is called:
Use of uninitialized value in array dereference at (eval 20) line 15 ( +#1) (W uninitialized) An undefined value was used as if it were already defined. It was interpreted as a "" or a 0, but maybe it was a mistake. To suppress this warning assign a defined value to your variables. Use of uninitialized value in array dereference at (eval 20) line 15. Use of uninitialized value in array dereference at (eval 20) line 16 ( +#1) Use of uninitialized value in array dereference at (eval 20) line 16. Use of uninitialized value in array dereference at (eval 20) line 22 ( +#1) Use of uninitialized value in array dereference at (eval 20) line 22. Use of uninitialized value in array dereference at (eval 20) line 22. Use of uninitialized value in array dereference at (eval 20) line 22.
I can't for the life of me work out what is wrong. The begining of the script is appended below. Any comments welcome. Regards, Stacy
#!/usr/local/bin/perl use DBI; use CGI qw/:standard/; use CGI::Carp qw(fatalsToBrowser); use diagnostics; use warnings; $fcolor = 'blue'; $bgcolor = '#FFFFFF'; $ENV{ORACLE_HOME} = '/path/to/orahome'; $base = 's/omedir'; $log = 'logfile'; %labels = (issue => 'Issue', reported_by => 'Reported By', date_occurred => 'Date Occurred', one_line_summary => 'One Line Summary', time_lost => 'Time Lost', response => 'Response', fix_status => 'Fix Status', fix_time => 'Fix Time', category => 'Category', date_range => 'Date Range');

Replies are listed 'Best First'.
Re: uninitialized value in array dereference
by chipmunk (Parson) on Jun 29, 2001 at 05:20 UTC
    It's impossible to say from the warning messages what the problem is, since it's occuring inside some anonymous eval statement. However, you can set up a handler for warnings that will print out a stack trace, showing where in the code this particular eval can be found, and the path your program took to get to it.
    $SIG{__WARN__} = sub { warn @_; my $i = 0; while (my($pkg, $file, $line) = caller($i++)) { warn " package $pkg, file $file, line $line\n"; } };
Re: uninitialized value in array dereference
by tachyon (Chancellor) on Jun 29, 2001 at 06:19 UTC

    To expand on chipmunks most excellent post what you are being told is:

    You are trying to access an undefined value (as explained by the diagnostic)

    This is occuring in the 20th eval that is called when your script runs.

    Within this eval the problem is the 15th, 16th and then 22nd line.

    What chipmunks code does is capture the warning signal. When a warning is generated this anonymous sub is run. First it prints the warning as normal (warn @_) as the warning message is passed to the sub in @_. The sub then utilises the caller() function to print some details of how the error occurred. Because one sub may call another, which in turn may call another.... caller allows you to specify if you want the caller, the caller's caller, the caller's caller's caller, etc. This is the function of the $i++ which directs caller further and further back until it finds the root caller.

    You could use Data::Dumper to dump all your varibale values in this sig warn to make life even easier.

    You might as a last resort manually hunt through your script for the possible errant eval statement given all the above details.

    cheers

    tachyon

(tye)Re: uninitialized value in array dereference
by tye (Sage) on Jun 29, 2001 at 21:01 UTC

    I've almost got PSI::ESP working on my machine and I think changing CGI.pm as follows will help (in addition to getting a stack trace back as already suggested). Old code from CGI.pm:

    sub _make_tag_func { my ($self,$tagname) = @_; my $func = qq( sub $tagname {
    to be changed to:
    sub _make_tag_func { my ($self,$tagname) = @_; my ($line,$file)= ( 3+__LINE__, __FILE__ ); my $func = qq( #line $line "$file/$tagname" sub $tagname {
    This may well transform your warnings into pointing to a specific line of CGI.pm/table, for example, telling you which line of CGI.pm to look at and that it was the table() method that had the problem.

    Hmm, seems a worthy patch to submit...

            - tye (but my friends call me "Tye")