Perl:将数组元素与hashmap值组合在一起

时间:2012-10-21 12:22:15

标签: arrays perl hashmap

我正在尝试将两个值粘贴在一个字符串中。一个值是数组元素,另一个值是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([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用于循环遍历数组,@ allLines包含读取文件中的所有行。 (<$fh>是我的文件句柄。)

编辑22-10-2012:我添加了整个代码以显示变量的位置

1 个答案:

答案 0 :(得分:1)

通常,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中连接在一起的值,这是我认为错误来自的地方。即使push为空,@completeLineArray也会有效,如果$fullLine出现问题,那么无论如何都会出现问题。

这很简单。只需复制上面的行,并使用say qq(DEBUG:));将其包围。要获得额外奖励积分,您可以在$前加一个反斜杠,以确保您没有任何问题。

say命令从5.10开始可用,并且很好,因为我不必继续将\n放在这些事情的最后,因为我剪切和粘贴会发生很多事情。您必须使用feature编译指示才能获得它。

我怀疑$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
}