0

我正在尝试使用 Perls 的 Tie::File::AsHash 将大文件加载到哈希中。但是,它似乎得到了键而不是值。代码是

#!/usr/bin/perl -w
use strict;
use Tie::File::AsHash;

tie my %what, 'Tie::File::AsHash', './test_tiehash', split => "\t" or die "Problem tying hash: $!";
foreach my $test(keys %what){
    print "$test $what{$test}\n";
}
untie %what

我正在对其进行测试的文件仅包含一行,最后一个数字后有一个制表符:

ENSMUSG00000020333|ENSMUST00000000145|54361198|54361535 AGAACGTTGCGGGGCGGGCGGCCCAGCCCCTCCCCCAGTCGGGCTCGGCAGTTCGGATGCCGCTAGATTGCTCTCTCACTTCTGGAGAAGATGCAGACCCAGGAGATCCTGAGGATCCTGCGGCTGCCCGAGCTATCGGACTTGGGCCAGTTTTTCCGCAGCCTCTCAGCTACCACCCTCGACGGTGGTGGAGCCCGGCGATCTGTGATTGGGGGTTGCACT

当我运行它时,我得到:在 ./test_hashes.pl 第 8 行第 2 行的连接 (.) 或字符串中使用未初始化的值。

有什么建议吗?提前致谢

4

1 回答 1

1

There is a bug in Tie::Array::AsHash (on which Tie::File::AsHash depends) whereby the key part of each line in the file is used as-is in a regular expression to extract the corresponding value. That means the value isn't found if any regex metacharacters appear in the key.

You can fix this temporarily for yourself by changing line 59 of Tie/Array/AsHash.pm from

my $fetchrx = qr/^$key$self->{split}(.*)/s;

to

my $split = $self->{split};
my $fetchrx = $split->isa('Regexp') ?
    qr/^\Q$key\E$split(.*)/s :
    qr/^\Q$key$split\E(.*)/s;

Alternatively, unless you need the facility whereby a change in the hash is reflected by modifying the contents of the file, you could just write some code like this

use strict;
use warnings;
use autodie;

my %what = do {
  open my $fh, '<', 'test_tiehash.txt';
  map { chomp; split /\t/; } <$fh>;
};

for my $test(keys %what){
  print "$test $what{$test}\n";
}

Meanwhile I shall mention this to the author of the module in the hope of getting it fixed in the near future.

于 2014-06-04T14:50:30.687 回答