use Devel::Memo;
sub number_cruncher {
local(*tough)=new Devel::Memo sub($$@) {
my ($arg1, $arg2, @others)=@_;
...calculate...
return $some_val, $some_other_val;
}, qw(-eq -equal -rest);
my @result1=tough 17, [1, 2];
my @result2=tough 15, {foo => 1}, 'bar';
my @result3=tough 15, {foo => 1}, 'bar'; # Faster!
}
The object is just a blessed subroutine reference, so you can call it directly or assign it to a typeglob to make it look like any other function call. The difference is that the object maintains an internal cache of previous invocations and their results, and returns a previous result directly if a set of arguments is ever duplicated (as defined by the ``prototype'', above). The cache is freed when the object leaves scope.
The implementing function is always called in array context; if the object is called in scalar context, the last value is returned.
Overhead in creating the hash key, etc. will make this module not worth your while unless the operations to be memoized are fairly time-consuming. An XSUB version would be nice...
Any bugs in FreezeThaw will presumably affect this module.
The use of FreezeThaw::safeFreeze actually oversteps FreezeThaw's documented guaranteed behavior in that it assumes that safeFreeze will return the same result for structurally equivalent arguments. Currently (FreezeThaw as in ILYAZ/etext/etext1.6.2.tar.gz) this is in fact the case, and it will probably remain so. If not, performance will suffer but the results should not be incorrect.