dannyjmh
dannyjmh

Reputation: 31

Tie::File::AsHash troubleshooting

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

Answers (1)

Borodin
Borodin

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

Related Questions