Perl Warning: Using an Uninitialized Value in a Connection or String

I get:

"Use of uninitialized value in join or string at ./test_script.pl line 69, <fh> line 91." 

The code generating this warning is here:

 # Write results of SQL execution to output file if ( $@ ) { print "\n DB Error : ", $@ ; exit; } open(FH, ">$output_file") or die "\n cannot write to the file $output_file. Check the file permissions"; while(my @row= $sth->fetchrow_array) { print FH join($delimiter, @row). "\n"; } 

It starts from the line "print ... join ...." in the "while" block, but I'm not sure if 100% of what causes it, and how to fix it.

The $ separator is initialized earlier as my $ delimiter = "|" and @row gets its values โ€‹โ€‹from the $ sth operation in the previous line.

Is this a โ€œtimeโ€ issue regarding @row values, or is it something in the processed actual SQL query file as indicated in the โ€œ<fh> line 91โ€ part of the warning part? Any ideas on how I can avoid the warnings? BTW, the script works fine, it just generates a warning for each @row value received, which creates a huge number of warnings with a large data set ...

+6
source share
1 answer

@row may contain some elements with an undefined value, probably because one or more columns in the database filled with @row were NULL . Behavior can be emulated when using join in a simple single-line Perl, such as:

 perl -we 'my @array = ("Hello",undef,"world!"); print join("|",@array) . "\n";' 

The conclusion to be made is as follows:

 Use of uninitialized value $array[1] in join or string at -e line 1. Hello||world! 

The reason for this is because join trying to join a value that it does not build without updating from "undefined" to "defined". The undef line displays this warning message, warning you that you can do something unintentional and wrong.

An even simpler example might be the following:

 $ perl -we 'my $scalar; print "$scalar\n";' Use of uninitialized value $scalar in concatenation (.) or string at -e line 1. 

Again, we get a warning because we interpolate the undefined value to a string. Interpolation causes a structure, and the construction of an undefined value usually triggers a warning so you know that you may have made a mistake.

If you don't mind silently updating undef to an empty line, you can do this:

 print FH join( $delimiter, map { defined ? $_ : '' } @row ) . "\n"; 

@row before passing it to join() . For each element in @row , if the element is undefined, this value is replaced by an empty string that is defined but visually quiet.

Another possibility is that $delimiter is undefined. Check it out by typing it, and if that turns out to be the case, the steps you need to take to fix it is just to make sure that it really contains the value.

Just the silence of warnings in a dense lexical field can also be in order, although from a philosophical point of view one method eliminates the cause and the other eliminates one of the symptoms. Method no warnings 'uninitialized'; , described elsewhere, does this only: silence warnings. You would do this when you know that you are doing something completely normal, but you also know that Perl is going to warn you about it, because many times this is a mistake. This can be such a situation: you can be completely happy just letting the soundless leveled undefined values โ€‹โ€‹happen inside join . And if so, continue and suppress the warning. what you know what this means, check what causes it, and then make an informed decision about what to do with it.

+11
source

Source: https://habr.com/ru/post/977841/


All Articles