1 package MiniMemoize; 2 use Exporter; 3 @ISA = qw(Exporter); 4 @EXPORT = qw(memoize); 5 use Carp; 6 use strict; 7 8 my %memotable; 9 10 sub memoize { 11 my $function = shift; 12 my $funcname; 13 if (ref $function eq '') { 14 my $caller = caller; 15 # Convert to code reference 16 $function = $caller . "::$function" unless $function =~ /::/; 17 $funcname = $function; 18 no strict 'refs'; 19 $function = \&$function; 20 } 21 22 my $stub = eval qq{sub { _check_cache("$function", \@_) }}; 23 $memotable{$function} = 24 { original => $function, 25 cache => { }, 26 }; 27 28 29 { no strict 'refs'; 30 *{$funcname} = $stub if defined $funcname; 31 } 32 $stub; 33 } 34 35 36 sub _check_cache { 37 my $what_func = shift; 38 unless (exists $memotable{$what_func}) { 39 # This `should never happen' 40 croak("Tried to check cache of non-memoized function `$what_func'; aborting"); 41 } 42 43 my $cache = $memotable{$what_func}{cache}; 44 my $argstr = join $;, @_; 45 if (exists $cache->{$argstr}) { return $cache->{$argstr} } 46 47 my $real_function = $memotable{$what_func}{original}; 48 $cache->{$argstr} = $real_function->(@_); 49 } 50 51 1;