【问题标题】:Perl: Combining array elements with hashmap valuesPerl:将数组元素与哈希图值组合
【发布时间】:2012-10-11 10:56:14
【问题描述】:

我正在尝试将两个值粘贴到一个字符串中。一个值是数组元素,另一个是 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 包含读取文件中的所有行。 (&lt;$fh&gt; 是我的文件句柄)。

2012 年 10 月 22 日编辑:我添加了整个代码以显示变量的生成位置

【问题讨论】:

  • 好吧,要么列表项是undef,要么哈希没有该值的键。我真的不明白我们如何能在这方面为您提供帮助。
  • David W. 在下面为您提供了一些很好的调试思路。如果您仍然遇到问题,则需要发布更多代码,因为问题不在这些行之外:显示设置 @allLines$index%fastaHash$key 的代码。
  • 我刚刚发布了更多代码。我希望这有助于理解我的问题

标签: arrays perl hashmap


【解决方案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 中连接在一起的值,我认为这是错误的来源。即使@completeLineArray 为空,push 也能正常工作,如果$fullLine 是问题所在,那么无论如何都会是上述行中的问题。

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

say 命令从 5.10 开始可用,这很好,因为我不必一直将\n 放在这些事情的末尾,因为我剪切和粘贴而经常发生这种情况。您必须使用 feature 杂注才能获得它。

我怀疑$key 不是您的%fastahash 哈希中的有效键。当您的哈希中不存在$key 时说$fastahash{$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
}

【讨论】:

  • 如果你想忽略某个变量的未初始化值,你也可以这样做:$fullLine = $allLines[$index] . "," . ($fastaHash{$key} // '');。这样您就不会丢失语句其他部分的警告。
  • 我添加了整个子程序的代码。我可能会告诉你这些值的来源。
猜你喜欢
  • 1970-01-01
  • 2014-05-12
  • 1970-01-01
  • 2021-08-01
  • 1970-01-01
  • 2012-04-28
  • 2016-05-19
  • 2013-11-01
  • 1970-01-01
相关资源
最近更新 更多