关于 Perl:Perl – 尝试访问存储为哈希值的数组时出错

Perl - error trying to access array stored as hash value

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

的循环

1
2
3
4
5
6
7
8
9
10
11
12
13
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."\
\\t$extraCmd\
\
"
;

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

>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 $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}}) 来做到这一点,但它的行为并不像我预期的那样。当我简单地要求它打印列表时:

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

我得到了预期的列表:

1
> 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

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

1
2
3
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";

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

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

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

干杯,
安娜


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

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

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

要么,

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

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

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

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