in reply to Memoize::Expire oddity

My first guess was to add LIST_CACHE => 'MERGE' to your memoize options. I tested it this way and your second example seems to work now. I didn't make any other changes.

I'm running Perl 5.14.2.

Replies are listed 'Best First'.
Re^2: Memoize::Expire oddity
by Random_Walk (Prior) on Aug 15, 2013 at 23:17 UTC

    I tried MERGE too and got the same error. I was using 5.16.2 on Windows. That's my work box. I'm home now on Linux, MERGE is also not helping me. am I using the option wrongly?

    r@Che ~ $ perl -MMemoize -MMemoize::Expire -E "sub f {int rand 100}; \ tie my %cache => 'Memoize::Expire',LIFETIME=>2,LIST_CACHE=>' +MERGE';\ memoize 'f',SCALAR_CACHE => [HASH => \%cache ];\ for (1..10) {say f(); sleep 1}" 45 45 45 45 45 45 45 45 45 45 r@Che ~ $ perl -v This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-li +nux-gnu-thread-multi (with 65 registered patches, see perl -V for more detail) Copyright 1987-2011, Larry Wall Perl may be copied only under the terms of either the Artistic License + or the GNU General Public License, which may be found in the Perl 5 source ki +t. Complete documentation for Perl, including FAQ lists, should be found +on this system using "man perl" or "perldoc perl". If you have access to + the Internet, point your browser at http://www.perl.org/, the Perl Home Pa +ge.

    Cheers,
    R.

    Pereant, qui ante nos nostra dixerunt!
      $ perl -MMemoize -MMemoize::Expire -E " \ sub f { int rand 100 }; \ tie my %cache => 'Memoize::Expire', LIFETIME => 2; \ memoize 'f', LIST_CACHE => 'MERGE', \ SCALAR_CACHE => [ HASH => \%cache ]; \ for (1..10) { say f(); sleep 1 }" 62 62 56 56 39 39 85 85 42
        Thanks for this example. With a little further modification it demonstrates that Memoize::Expire won't work for functions returning lists:
        perl -MMemoize -MMemoize::Expire -E " \ sub f { ('X',int rand 100) }; \ tie my %cache => 'Memoize::Expire', NUM_USES => 3; \ memoize 'f', LIST_CACHE => 'MERGE', \ SCALAR_CACHE => [ HASH => \%cache ]; \ for (1..6) { say f() }"
        X63
        X
        X
        X67
        X
        X
        
        You should be able to use any tied hash- not only Memoize::Expire but also any of the file-stores- if you first wrap it in something that will freeze/thaw the list beforehand. Example:
        perl -MMemoize -MMemoize::Expire -MSerializeValues -E " \ sub f { ('X',int rand 100) }; \ tie my %subcache => 'Memoize::Expire', NUM_USES => 3; \ tie my %cache => 'SerializeValues', \%subcache; \ memoize 'f', LIST_CACHE => [ HASH => \%cache ], \ SCALAR_CACHE =>'MERGE' ; \ for (1..6) { say f() }"
        X73
        X73
        X2
        X2
        X64
        X64
        
        Below is my SerializeValues wrapper. Note that it seems to call the sub-cache's "FETCH" while it stores, effectively reducing NUM_USES by one. Also since Serialize requires a reference, it has to be in the LIST_CACHE slot, not SCALAR_CACHE.
        #!/usr/bin/env perl package SerializeValues; require Tie::Hash; @ISA = qw(Tie::ExtraHash); use strict; use warnings; use Storable qw[freeze thaw]; sub TIEHASH { my ($class, $child_hash) = @_; return bless [$child_hash], $class; } sub STORE { $_[0][0]{$_[1]}= freeze $_[2] } sub FETCH { thaw $_[0][0]{$_[1]} }
        I'm going to email the author (mjd) and suggest adding a flag to the HASH option to say that the values should be serialized first.

        PS. This module is over a decade old, and within a couple weeks two of us independently run into the same limitation- there's something going around...