in reply to initialize all values in a hash

If you know the keys in advance, it's relatively easy:

use Data::Dumper; my %hash = map { $_ => 60; } qw(foo bar baz); print Dumper \%hash;

If you don't... well... that's not how hashes work. You could do it with a tied hash, but I can't find a module that does this on CPAN, so you'd need to do it yourself.

But it would be better to modify the code that reads from the hash so that before it reads from the hash, it checks whether that value exists in the hash, and substitutes 60 if not.

perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Replies are listed 'Best First'.
Re^2: initialize all values in a hash
by tobyink (Canon) on May 18, 2012 at 13:58 UTC

    "You could do it with a tied hash, but I can't find a module that does this on CPAN, so you'd need to do it yourself."

    OK, I've just gone and uploaded Hash::DefaultValue to CPAN. Usage:

    tie my %hash, 'Hash::DefaultValue', 60; $hash{foo} = 8; say $hash{foo}; # says 8 say $hash{bar}; # says 60
    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

        Oh, that's annoying. In fairness, a documented feature of mine is that it explicitly avoids autovivifying keys. So with Tie::Hash::Vivify, this is true:

        tie my %hash, 'Tie::Hash::Vivify', sub { 10 }; say $hash{foo}; # says 10 my $is_this_true = exists $hash{foo};

        Whereas this is false:

        tie my %hash, 'Hash::DefaultValue', sub { 10 }; say $hash{foo}; my $is_this_true = exists $hash{foo};

        Another feature of Hash::DefaultValue is that the coderef gets passed a copy of the key, so can use that information when generating the default value.

        tie my %hash, 'Hash::DefaultValue', sub { uc }; say $hash{foo}; # says "FOO"
        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re^2: initialize all values in a hash
by AWallBuilder (Beadle) on May 18, 2012 at 11:02 UTC

    Thank you for the suggestion of the other way. I now check and if it is the first time it sees this query it will assign the current bit_score as the max, and then check all subsequent ones to see if they are bigger.

    and maybe I'll re-read the llama book. It was a while ago and I left Perl for a few years, and seem to have a selective memory.

    my $in_blast_tab=$ARGV[0]; open(IN,$in_blast_tab) or die "cannot open $in_blast_tab\n"; my $HoFlg1={}; my $HoFlg2={}; my %maxBits; while (my $line=<IN>) { next if ($line =~ /^#/); next unless ($line =~ /\S/); chomp $line; my ($Query_id,$strand,$Subj_id,$Perc_iden,$align_len,$num_mm,$ +gap,$q_start,$q_end,$s_start,$s_end,$e_value,$bit_score)=split("\t",$ +line); # extra field of strand next if ($bit_score <60); if (!exists $maxBits{$Query_id}){ $maxBits{$Query_id}=$bit_score; } elsif (exists $maxBits{$Query_id} && $bit_score > $maxBits{$Qu +ery_id}){ $maxBits{$Query_id}=$bit_score; } my ($Flag1, $Flag2 ) = &Flag( $Subj_id, \%proph_prots, \%euk_p +rots, \%vir_prots ); $HoFlg1->{$Query_id}->{$Flag1}->{$bit_score}++; $HoFlg2->{$Query_id}->{$Flag2}->{$bit_score}++; print join("\t",$Query_id,$Subj_id,"bit",$bit_score,"F1",$Flag +1,"F2",$Flag2,"maxBits{Query}",$maxBits{$Query_id})."\n"; }