Okay. I took your version of the sub -- which I don't see anything wrong with; though it could be simplified somewhat -- and plugged it into my testscript from above:
#! perl -slw
use strict;
use Data::Dump qw[ pp ];
sub genPickerConverted {
my %kmer_prob = %{ $_[0] };
my @vals = keys %kmer_prob;
my @odds = ();
foreach my $val (@vals) {
push (@odds, $kmer_prob{$val});
}
my @order = sort{ $odds[ $a ] <=> $odds[ $b ] } 0 .. $#odds;
@odds = @odds[ @order ];
@vals = @vals[ @order ];
my $t = 0; $t += $_ for @odds;
$_ /= $t for @odds;
$odds[ $_ + 1 ] += $odds[ $_ ] for 0 .. $#odds - 1;
return sub {
my $r = rand();
$r < $odds[ $_ ] and return $vals[ $_ ] for 0 .. $#odds;
};
}
my %kmer_probe = map{ split( ' ' ) } <DATA>;
pp \%kmer_probe;
my $picker = genPickerConverted( \%kmer_probe );
my %tally; ++$tally{ $picker->() } for 1 .. 1e6;
pp \%tally;
__DATA__
A 1e-7
B 20e-7
C 10e-5
And it produces: C:\test>junk997.pl
{ A => 1e-7, B => 20e-7, C => 10e-5 }
{ A => 971, B => 19509, C => 979520 }
Which is exactly what I'd expect.
So, as I don't really understand what you mean by:
why does my code not get in there when I pass my vals and odds to the subroutine as a hash rather than a file handle?
You're going to have to clarify what you mean by that.
However, having re-read your prior post, I saw something that didn't mean anything at my first reading:" but then it never enters the "return" block."; and that maybe the clue to your confusion.
The anonymous subroutine that is returned by the function will not be entered at that time. The return statement is return a reference to that anonymous subroutine, that gets assigned to the variable my $picker = genPickerConverted( \%kmer_probe ); in the main program.
That subroutine doesn't get executed (entered) until you dereference the $picker variable by doing: $picker->();. Only then does teh subroutine get run.
Does that explain your problem?
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
|