Skip Menu |

This queue is for tickets about the Memoize CPAN distribution.

Report information
The Basics
Id: 91927
Status: new
Priority: 0/
Queue: Memoize

People
Owner: Nobody in particular
Requestors: SREZIC [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 1.03
Fixed in: (no value)



Subject: SCALAR_CACHE=>[HASH=>...] and LIST_CACHE=>MERGE broken
The combination SCALAR_CACHE => [HASH => \%cache], LIST_CACHE => 'MERGE' is broken with 1.03. Memoization still work, but the referenzed cache hash is not used anymore. See the attached test script merge.t: this script works with Memoize 1.02 but fails with version 1.03. (The test script should be suitable for inclusion into the Memoize distribution) Regards, Slaven
Subject: merge.t
#!/usr/bin/perl use lib '..'; use Memoize 'memoize'; use Test::More; plan tests => 8; my %cache; my $cacheit_counter; sub cacheit { $cacheit_counter++; "cacheit result"; } memoize 'cacheit', SCALAR_CACHE => [HASH => \%cache], LIST_CACHE => 'MERGE'; { my $s = cacheit(); is $s, 'cacheit result', 'scalar context'; is $cacheit_counter, 1, 'function called once'; } { my @s = cacheit(); is $s[0], 'cacheit result', 'list context'; is $cacheit_counter, 1, 'function not called'; } cmp_ok keys %cache, ">", 0, 'cache hash is filled'; is((values(%cache))[0], 'cacheit result', 'expected cached value'); %cache = (); { my @s = cacheit(); is $s[0], 'cacheit result', 'list context'; is $cacheit_counter, 2, 'function again called after clearing the cache'; }
On 2014-01-07 11:18:15, SREZIC wrote: Show quoted text
> The combination SCALAR_CACHE => [HASH => \%cache], LIST_CACHE => > 'MERGE' is broken with 1.03. Memoization still work, but the > referenzed cache hash is not used anymore. See the attached test > script merge.t: this script works with Memoize 1.02 but fails with > version 1.03. (The test script should be suitable for inclusion into > the Memoize distribution)
Attached an attempt to fix the problem. Note that the patch assumes that the previously provided file t/merge.t is already on disk. I also noticed a possible behavior change between 1.02 and 1.03: if SCALAR_CACHE=>[HASH=>\%cache], LIST_CACHE=>"MERGE" is specified, then formerly the cached values in %cache were just scalars, but now it's always array references. I don't know if this change was intended. Regards, Slaven
Subject: 0001-fix-for-RT-91927.patch
From 8df79244721f0bef067c434710ea16e5d988c43c Mon Sep 17 00:00:00 2001 From: Slaven Rezic <slaven.rezic@idealo.de> Date: Tue, 7 Jan 2014 17:32:14 +0100 Subject: [PATCH] fix for RT #91927 change t/merge.t as cache values are array refs in case of merged caches --- Memoize.pm | 6 +++++- t/merge.t | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/Memoize.pm b/Memoize.pm index 9a58c4a..67288ce 100644 --- a/Memoize.pm +++ b/Memoize.pm @@ -134,7 +134,11 @@ sub memoize { # both get merged to the same in-memory hash. if ($options{SCALAR_CACHE} eq 'MERGE' || $options{LIST_CACHE} eq 'MERGE') { $options{MERGED} = 1; - $caches{SCALAR} = $caches{LIST}; + if ($options{SCALAR_CACHE} eq 'MERGE') { + $caches{SCALAR} = $caches{LIST}; + } else { + $caches{LIST} = $caches{SCALAR}; + } } # Now deal with the TIE options diff --git a/t/merge.t b/t/merge.t index cc1393b..b34ef7e 100644 --- a/t/merge.t +++ b/t/merge.t @@ -29,7 +29,7 @@ memoize 'cacheit', SCALAR_CACHE => [HASH => \%cache], LIST_CACHE => 'MERGE'; } cmp_ok keys %cache, ">", 0, 'cache hash is filled'; -is((values(%cache))[0], 'cacheit result', 'expected cached value'); +is((values(%cache))[0]->[0], 'cacheit result', 'expected cached value'); %cache = (); -- 1.7.9.5
Attached another script which is broken in Memoize 1.03. It is modelled after the example code in https://metacpan.org/pod/Memoize#Merged-disk-caches (just with correct MLDBM usage and without the normalizer function). With Memoize 1.02, the disk cache works and "myfunc called" is printed only the first time. With Memoize 1.03, disk caching does not work and "myfunc called" is printed on every script invocation. Regards, Slaven
Subject: memdisk.pl
use Memoize; use MLDBM; use DB_File; use Fcntl qw(O_CREAT O_RDWR); local $MLDBM::UseDB = 'DB_File'; tie my %cache => 'MLDBM', "/tmp/test.mldbm", O_CREAT|O_RDWR, 0666; memoize 'myfunc', SCALAR_CACHE => [HASH => \%cache], LIST_CACHE => 'MERGE', ; sub myfunc { warn "myfunc called"; "something"; } myfunc(); myfunc();