Reputation: 31
I'm trying to use Perls's Tie::File::AsHash to load a big file into a hash. However, it seems to get keys but not the values. The code is
#!/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
The file I'm testing it on contains one only line, with a tab after the last number:
ENSMUSG00000020333|ENSMUST00000000145|54361198|54361535 AGAACGTTGCGGGGCGGGCGGCCCAGCCCCTCCCCCAGTCGGGCTCGGCAGTTCGGATGCCGCTAGATTGCTCTCTCACTTCTGGAGAAGATGCAGACCCAGGAGATCCTGAGGATCCTGCGGCTGCCCGAGCTATCGGACTTGGGCCAGTTTTTCCGCAGCCTCTCAGCTACCACCCTCGACGGTGGTGGAGCCCGGCGATCTGTGATTGGGGGTTGCACT
When i run it, I get: Use of uninitialized value in concatenation (.) or string at ./test_hashes.pl line 8, line 2.
Any suggestion? Thanks in advance
Upvotes: 0
Views: 158
Reputation: 126742
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.
Upvotes: 1