Reputation: 199
I'm trying to paste two values together in a string. One value is an array element and the other a hashmapvalue. But I keep having this error:
Use of uninitialized value in concatenation (.) or string
at makeNewCSV.pl line 104, <$fh> line 2020.
This is my code:
use feature qq(say);
my @nodeIdArray;
my @sequenceArray;
my @completeLineArray;
my %fastaHash = ();
[...]
sub readCsv{#Reads the CSV and puts all the Node ID's in an array
my ($file) = @_;
my $nodeID = qr{\d+\,(\d+)};
open(my $fh, '<', $file) or die "Error while reading CSV: $!";
while(my $line = <$fh>){
if($line =~ $nodeID){
push(@nodeIdArray, $1);
}
}
close($fh);
searchFasta();
}
sub searchFasta{#Reads and searches the fasta file for contigs with a matching node ID
my ($file) = $ARGV[1];
my $fastaNodeID = qr{>NODE_(\d+)_LENGTH_\d+_COV_[\d.]+\n([ACTGN\n]+)};
my @matches;
open(my $fh, '<', $file) or die "Error while reading fasta: $!";
my @allLines = <$fh>;
my $makeString = join('', @allLines);
my $lineAsString = uc($makeString);
while($lineAsString =~ m/$fastaNodeID/g){
my $node_ID = $1;
my $sequence = $2;
$sequence =~ s/\n//;
$fastaHash{$node_ID} = $sequence;
}
close($fh);
pasteLines();
}
sub pasteLines{
my $fullLine = "";
my $file = $ARGV[0];
my @hashKeys = keys(%fastaHash);
my $index = 0;
my $numberOfRepeat = 0;
open(my $fh, '<', $file) or die "Error while reading CSV (2): $!";
my @allLines = <$fh>;
my $arrayLength = @allLines;
foreach my $line(@allLines){
chomp($line);
}
while($numberOfRepeat <= $arrayLength){
foreach my $key(@hashKeys){
if($key = $nodeIdArray[$index]){
no warnings qw(uninitialized); #DEBUG:
say qq(DEBUG: \$fastaHash{$key} = "$fastaHash{$key}");
say qq(DEBUG: \$fullLine = $allLines[$index] . "," . $fastaHash{$key};);
use warnings qw(uninitialized); #DEBUG:
$fullLine = $allLines[$index] . "," . $fastaHash{$key}; #This line here gives the problems
push(@completeLineArray, $fullLine);
$index++;
}
else{
$index++;
}
}
}
close($fh);
}
$index is for looping through the array and @allLines contains all the lines from a read file. (<$fh>
is my filehandle).
Edit 22-10-2012: I added the entire code to show where the variables are made
Upvotes: 1
Views: 222
Reputation: 107090
Usually, Perl is pretty good at picking the exact line number in undefined issues.
Apparently, somewhere, something you think has a value doesn't. The easiest way to solve this is to simply print out the values before you do anything else. Try this:
use feature qq(say);
[...]
no warnings qw(uninitialized); #DEBUG:
say qq(DEBUG: \$fastaHash{$key} = "$fastaHash{$key}");
say qq(DEBUG: \$fullLine = $allLines[$index] . "," . $fastaHash{$key};);
use warnings qw(uninitialized); #DEBUG:
$fullLine = $allLines[$index] . "," . $fastaHash{$key};
push(@completeLineArray, $fullLine);
This will print out the values you're trying to concatenate together in $fullline
which is where I believe the error is coming from. The push
will work even if @completeLineArray
is empty, and if $fullLine
is the problem, it would be a problem in the line above anyway.
This is fairly simple to do. Simply copy out the line above and surround it with say qq(DEBUG:)
and );
. For extra bonus points, you can put a backslash in front of the $
just to make sure you don't have any problems with that.
The say
command is available since 5.10, and is nice because I don't have to keep putting the \n
at the end of these things which happens a lot because I cut and paste. You have to use the feature pragma in order to get it.
My suspicion is that $key
is not a valid key in your %fastahash
hash. Saying $fastahash{$key}
when $key
doesn't exist in your hash will return an undefined value. Since you didn't post much else, I can't say why $key
would point to a non-existant value. However, I bet once you start printing out these keys, you'll quickly find the issue.
The no warnings qw(uninitialized)
will stop printing out that uninitialized warning. I know that some value will be uninitailized in the DEBUG:
statements. That's why I am printing them. However, reenable the uninitialized warnings before your statement, so that you still get that warning. You see that in your output, and you can look for the DEBUG:
statements above to see what the issue could be.
After you figure out the problem, you can easily remove the DEBUG:
lines with a search and delete.
Now, there are two ways of handling this error once you find it:
Just surround the code with the no warnings qw(uninitialized);
and use warnings qw(initialized);
statements. It's quick and simple and the program just might be doing what you want anyway. Besides, we all know if you ignore a problem, it just goes away.
If, what I suspect is that $key
is not pointing to a valid key in your array, then you can catch that error and handle it. It might simply be not pushing that value into your @completeLineArray
array, or it might be some other error handling technique. Below, I check for two possibilities: That $key
doesn't point to a valid entry in %fastaHash
, or that $key
does actually point to a valid entry in your %fastaHash
, but that value is undefined:
if ( defined $fastaHash{$key} ) {
$fullLine = $allLines[$index] . "," . $fastaHash{$key};
push(@completeLineArray, $fullLine);
}
elsif ( not exists $fashaHash{$key} ){ #Key could exist, but value be `undef`
...; #What you want to do if value key points to is undefined.
}
else (
...; #What you want to do if $key doesn't point to a key in your hash
}
Upvotes: 1