Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Most Annoying Error : Use of uninitialized value in concatenation (.) or string at C:\Perl\O

by graff (Chancellor)
on Jul 15, 2005 at 12:21 UTC ( [id://475192]=note: print w/replies, xml ) Need Help??


in reply to Most Annoying Error : Use of uninitialized value in concatenation (.) or string at C:\Perl\O

Grandfather is right. The warning is telling you that you are not checking the contents of @db_values before sending them into an operation where you might not want them to be undef (e.g. inserting a row in a database that contains nothing but null values). It's even telling you which line in the data file is causing the problem.

An easy way to avoid the warning -- and make sure you only insert rows that have the expected amount of actual data -- would be:

my @db_values = split (/,/,$entry); next unless ( @db_values == 7 ); ## add this line $DB->sql("INSERT INTO Files ... ");
You have another symptom of being too trusting: you pass  $ARGV[0] to the open statement without checking to see if the user supplied an arg on the command line.

In your case (opening a file for input), die would say "No such file or directory" after you get the warning "Use of uninitialized value in open". Oddly enough when I just now tested an open for output with nothing in @ARGV, I got no warning, no error, and no output file -- which makes it a really tricky thing to catch. (That seems like a perl bug, and worthy of a separate thread...)

Anyway, you should always check input (from users or data files) before using it.

update: forgot to mention -- are you sure you want to be using DBI to insert stuff into the database? It's very slow and you have to do all the work yourself (which you have not been doing yet) of checking that the values are appropriate before inserting them. I expect that your database engine (whatever it is) has its own tool or method for inserting data from a file, which will run a lot quicker (and value checks are likely to be built-in); note that you can (and should) use perl to condition data in advance if needed, and to run that tool.

  • Comment on Re: Most Annoying Error : Use of uninitialized value in concatenation (.) or string at C:\Perl\O
  • Select or Download Code

Replies are listed 'Best First'.
Re^2: Most Annoying Error : Use of uninitialized value in concatenation (.) or string at C:\Perl\O
by Steve_p (Priest) on Jul 15, 2005 at 17:34 UTC
    my @db_values = split (/,/,$entry); next unless ( @db_values == 7 ); ## add this line $DB->sql("INSERT INTO Files ... ");

    I don't see how that would work if the array is actually filled with undef's. For example...

    steve@kirk:~$ perl -wle'push @foo, undef for (0..6); print scalar @foo +' 7

    Your code will only work if you don't have 7 entries in the array. It doesn't do any more checking of the data than that. More checks are needed to guarantee it will work.

    A more appropriate question, though, is why the OP is not letting the database do the work for him? jhourcle's entry below suggesting a prepare is probably the best reply here. Let the database do the checks for NULL values then. Simply turning off warnings is not really solving the problem. It's a bit like using duct tape. Its a repair, but not a real fix. Also, there should be a performace boost by not having to repeatedly reparse the insert multiple times.

    Also, regarding the question on an empty $ARGV[0] to open(). I did run into issues, but I had not problems with it die'ing. My problem is that $! wasn't getting populated without using strict on a one-liner. I will open a perlbug for this problem, but I could not see where open was failing to behave as expected. Hopefully, I can get a fix for my problem done this evening.

    steve@kirk:~$ perl -wle'open FOO, undef || die "FOO! $!";' Name "main::FOO" used only once: possible typo at -e line 1. FOO! at -e line 1. steve@kirk:~$ perl -Mstrict -wle'open FOO, undef || die "FOO! $!";' Name "main::FOO" used only once: possible typo at -e line 1. FOO! Bad file descriptor at -e line 1.
      I don't see how that would work if the array is actually filled with undef's.

      The way that split works (with the two argument call as in the OP), an empty or undef input string will yield a list of zero elements, so "scalar @db_values" in that case will be zero. Likewise, if the input string is something like just "a" or "a,,,,,,", split will return a list of just one element (scalar @db_values will be "1"), and so on; trailing separators, if any, are simply truncated.

      It's true that if a line of input text contained a string like ",,,,,,g", split will return a list of 7 elements, the first six of which will be undef. But in that case, it might actually be "right" to create a database record in which the first six fields are null.

      It's also true that more checking of input values, before sending them on to a database, would be prudent, and more efficient ways of inserting database rows are both available and recommended (e.g. using the DB engine's native file import tools).

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://475192]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others wandering the Monastery: (3)
As of 2024-04-26 02:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found