我试图将两个值粘贴到字符串中。一个值是一个数组元素,另一个值是hashmapvalue。但是我一直存在这个错误:
Use of uninitialized value in concatenation (.) or string
at makeNewCSV.pl line 104, <$fh> line 2020.
这是我的代码:
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([ACTGNn]+)};
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);
}
$索引用于通过数组循环,@Alllines包含读取文件中的所有行。( <$fh>
是我的filehandle)。
编辑22-10-2012:我添加了整个代码以显示变量的位置
通常,perl非常擅长在未定义的问题中选择确切的行号。
显然,某个地方,您认为具有价值的东西没有。解决此问题的最简单方法是在做其他任何事情之前简单地打印出值。尝试以下操作:
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);
这将打印出您想在$fullline
中加入在一起的值,这是我认为错误来自的地方。即使@completeLineArray
为空,push
也可以工作,如果$fullLine
是问题,则无论如何,这将是上面的问题。
这很简单。只需复制上方的行,并用say qq(DEBUG:)
和);
包围。对于额外的奖励积分,您可以在$
的前面放置后斜切,以确保您对此没有任何问题。
say
命令自5.10起就可以使用,而且很不错,因为我不必继续将n
放在这些事情的末尾,因为我剪切和粘贴了。您必须使用功能Pragma才能获得。
我的怀疑是$key
不是%fastahash
哈希中的有效键。说$fastahash{$key}
当您的哈希中不存在$key
时,将返回不确定的值。由于您没有发布太多其他信息,所以我不能说$key
为什么要指出不存在的值。但是,我敢打赌,一旦您开始打印这些钥匙,您就会很快找到问题。
no warnings qw(uninitialized)
将停止打印该非初始化的警告。我知道在DEBUG:
语句中某些价值将未经验证。这就是为什么我要打印它们。但是,在您的陈述之前,可以重新确定非初始化的警告,以便您仍然明确警告。您会在输出中看到这一点,并且可以查看上面的DEBUG:
语句以查看问题。
找出问题后,您可以轻松地使用搜索并删除DEBUG:
行。
现在,一旦找到此错误,就有两种方法:
忽略它
只需用no warnings qw(uninitialized);
和use warnings qw(initialized);
语句包围代码即可。它很简单,而且该程序可能无论如何都可以做您想做的事情。此外,我们都知道您是否忽略了一个问题,它就消失了。
处理错误
如果我怀疑$key
没有指向数组中的有效键,那么您可以捕获该错误并处理。它可能根本不会将该值推入您的@completeLineArray
数组,或者可能是其他错误处理技术。下面,我检查了两种可能性:$key
并未指向%fastaHash
中的有效条目,或者$key
实际上确实指向%fastaHash
中的有效条目,但该值未定义:
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
}