【问题标题】:Perl - error trying to access array stored as hash valuePerl - 尝试访问存储为哈希值的数组时出错
【发布时间】:2015-04-28 07:51:16
【问题描述】:

我遇到了一个较大脚本的一小部分的问题。我正在尝试将文件名作为哈希值存储在数组中,以便以后能够将它们全部列出。下面是我构建哈希 %extramapped 的循环:

for (my $i=0; $i<scalar(@refgenomes); $i++) {
            my $extraRefPath = $refgenomes[$i];
            my @extraFieldRef = split("/", $extraRefPath);
            my @extraFullRefName = split("\\.", $extraFieldRef[-1]);
            my $extraRefName = $extraFullRefName[0];
            my $extraTempOutFile = $gzFile.$extraRefName.".sort.bam";
            my $extraCmd = "$bwa bam2bam -n 0.01 -o 2 -l 16500 -g $extraRefPath <($fixpair -o /dev/stdout $tempOutFile) | samtools sort -o /dev/stdin ".$gzFile.".sort"." >$extraTempOutFile";
            push(@listTargets, $extraTempOutFile);
            push(@{$extramapped{$extraRefName}}, $extraTempOutFile);
            $stringMakeToPrint = $stringMakeToPrint.$extraTempOutFile.": ".$tempOutFile."\n\t$extraCmd\n\n";

当我使用 Data::Dumper 检查哈希的内容时,它看起来和我预期的一样:

>

 $VAR1 = {
>           'rCRS' => [
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L001_R1_001.fastq.gzrCRS.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L001_R1_002.fastq.gzrCRS.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L001_R1_003.fastq.gzrCRS.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L002_R1_001.fastq.gzrCRS.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L002_R1_002.fastq.gzrCRS.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L002_R1_003.fastq.gzrCRS.sort.bam'
>                     ],
>           'Copy_NC' => [
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L001_R1_001.fastq.gzCopy_NC.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L001_R1_002.fastq.gzCopy_NC.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L001_R1_003.fastq.gzCopy_NC.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L002_R1_001.fastq.gzCopy_NC.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L002_R1_002.fastq.gzCopy_NC.sort.bam',
> '..//Sample_LP30/LP30_CCTAGGT-ACCTAGG_L002_R1_003.fastq.gzCopy_NC.sort.bam'
>                        ]
>         };

但是,我很难恢复这些文件名。我虽然可以使用 join(" ", @{$extramapped{$extraRefName}}) 来做到这一点,但它的行为并不像我预期的那样。当我只是要求它这样打印列表时:

my $extraFileList = join(" ", @{$extramapped{$extraRefName}});
print "This is the extra file list $extraFileList\n";

我得到了预期的列表:

> This is the extra file list ..//Sample_LP32/LP32_GCTCGAA-ACTTCAA_L001_R1_001.fastq.gzCopy_NC.sort.bam ..//Sample_LP32/LP32_GCTCGAA-ACTTCAA_L001_R1_002.fastq.gzCopy_NC.sort.bam ..//Sample_LP32/LP32_GCTCGAA-ACTTCAA_L002_R1_001.fastq.gzCopy_NC.sort.bam ..//Sample_LP32/LP32_GCTCGAA-ACTTCAA_L002_R1_002.fastq.gzCopy_NC.sort.bam

但是当我尝试将其合并到这样的循环中时:

for (my $i=0; $i<scalar(@refgenomes); $i++) {
    my $extraFileList = join(" ", @{$extramapped{$extraRefName}});
    my $extraMmfCmd = "$samtools merge $extraFileList | $retrieve /dev/stdin /dev/stdout | $rmdup -c -o $extraMapFileName /dev/stdin";

我收到以下错误并且循环终止。

> Can't use an undefined value as an ARRAY reference at line 152.

我不明白为什么在这种情况下输出不同。谁能给我解释一下?建议如何解决?

干杯, 安娜

【问题讨论】:

  • $extramaped{$extraRefName} 是否有可能在程序中超出范围? (%extramaped 或 $extraRefName)
  • 我不认为可能是这样,当我放入 print 语句进行测试时,我将它放在我的 $extraMmfCmd 正上方并且它打印得很好。
  • 您可以尝试在循环开始之后和“my $extraFileList...”部分之前直接放置更多打印语句...例如,打印 $extraRefName 的值,然后打印“ ref $extramapped{$extraRefName}" (它应该给你 ARRAY,但它可能不会。如果没有,那么尝试在循环前将 print 语句向上移动几行,看看你是否在那里得到 ARRAY。跨度>
  • 这是个好主意,谢谢。我意识到它在通过循环的第 4 次迭代中死亡,检查并发现第 4 个输入违反了模式,因此它试图不向数组传递任何内容。现在工作得很好。干杯。

标签: arrays perl hash bioinformatics


【解决方案1】:

@{...} dereferences 一个数组引用。所以如果它在这里爆炸:

my $extraFileList = join(" ", @{$extramapped{$extraRefName}});

那么这显然是$extramapped{$extraRefName} 没有存储对取消引用的数组引用的结果。

要么,

  • $extraRefName 不再引用有效密钥
  • 或者,$extramapped{$extraRefName} 被其他地方的某事删除了。

有些人采用了避免此错误的做法,通过 or-ing 将其与空数组引用:@{ $hash{ $keyNotThere } || [] }。虽然,这在创建数组时往往有点浪费。你真正想要的是一个更繁琐的:

ref( $aref ) eq 'ARRAY' ? @$aref : ();

(当然,Perl 向导可能已经优化了空数组取消引用。)

【讨论】:

  • 正如我上面提到的它对ratsbane 的响应,问题原来是输入而不是脚本本身。感谢您的解释,我将不得不再研究一下这个 ref eq ARRAY 符号。干杯。
猜你喜欢
  • 2023-03-15
  • 2017-10-04
  • 1970-01-01
  • 2013-06-06
  • 2013-08-21
  • 1970-01-01
  • 2010-12-20
  • 2016-12-12
  • 1970-01-01
相关资源
最近更新 更多