Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl: why does $hashsize = keys $hash{$foo} give experimental warning, and how can I write it better?

I have a hash determined by two factors (I don't know what the correct term for this is), which I generate like so:

if (exists $cuthash{$chr}{$bin}){
    $cuthash{$chr}{$bin} += 1;
}else{
    $cuthash{$chr}{$bin} = 1;
}

I later want to grab the size of each $chr portion of the hash, which works when I do:

for my $chr (sort keys %cuthash){
    my $hashsize = keys $cuthash{$chr};
    ...
}

but I get the warning:

keys on reference is experimental at ../test.pl line 115.

It works, but obviously it's not perfect. What is a better method?

Thanks

like image 576
Daniel Avatar asked Dec 19 '22 04:12

Daniel


2 Answers

If you dereference the hashref

my $hashsize = keys %{ $cuthash{$chr} };

then there should be no warning.

like image 115
dgw Avatar answered May 24 '23 19:05

dgw


There is no need to test for the existence of $cuthash{$chr}{$bin} if you use ++ instead of += 1 since it doesn't warn when its operand is undef. Just write

++$cuthash{$chr}{$bin};

instead of the whole of your if statement.

In situations like this it can be tidier to extract a local copy of the hash value, either explicitly or using each. That way there is no need for a block to delimit the reference expression, so you can write %$hashref instead of %{ $cuthash{$chr} }. Like so

for my $chr (sort keys %cuthash) {
    my $val = $cuthash{$chr};
    my $hashsize = keys %$val;
    ...
}

or

while ( my ($key, $val) = each %cuthash) {
    my $hashsize = keys %$val;
    ...
}

I am sure you can think of a more sensible name for $val that reflects its purpose

like image 32
Borodin Avatar answered May 24 '23 20:05

Borodin