1use strict; use warnings; 2use Memoize qw(memoize unmemoize); 3use Test::More tests => 26; 4 5is eval { unmemoize('u') }, undef, 'trying to unmemoize without memoizing fails'; 6my $errx = qr/^Could not unmemoize function `u', because it was not memoized to begin with/; 7like $@, $errx, '... with the expected error'; 8 9sub u {1} 10my $sub = \&u; 11my $wrapped = memoize('u'); 12is \&u, $wrapped, 'trying to memoize succeeds'; 13 14is eval { unmemoize('u') }, $sub, 'trying to unmemoize succeeds' or diag $@; 15 16is \&u, $sub, '... and does in fact unmemoize it'; 17 18is eval { unmemoize('u') }, undef, 'trying to unmemoize it again fails'; 19like $@, $errx, '... with the expected error'; 20 21# Memoizing a function multiple times separately is not very useful 22# but it should not break unmemoize or make memoization lose its mind 23 24my $ret; 25my $dummy = sub { $ret }; 26ok memoize $dummy, INSTALL => 'memo1'; 27ok memoize $dummy, INSTALL => 'memo2'; 28ok defined &memo1, 'memoized once'; 29ok defined &memo2, 'memoized twice'; 30$@ = ''; 31ok eval { unmemoize 'memo1' }, 'unmemoized once'; 32is $@, '', '... and no exception'; 33$@ = ''; 34ok eval { unmemoize 'memo2' }, 'unmemoized twice'; 35is $@, '', '... and no exception'; 36is \&memo1, $dummy, 'unmemoized installed once'; 37is \&memo2, $dummy, 'unmemoized installed twice'; 38 39my @quux = qw(foo bar baz); 40my %memo = map +($_ => memoize $dummy), @quux; 41for (@quux) { $ret = $_; is $memo{$_}->(), $_, "\$memo{$_}->() returns $_" } 42for (@quux) { undef $ret; is $memo{$_}->(), $_, "\$memo{$_}->() returns $_" } 43 44my $destroyed = 0; 45sub Counted::DESTROY { ++$destroyed } 46{ 47 my $memo = memoize $dummy, map +( "$_\_CACHE" => [ HASH => bless {}, 'Counted' ] ), qw(LIST SCALAR); 48 ok $memo, 'memoize anon'; 49 ok eval { unmemoize $memo }, 'unmemoized anon'; 50} 51is $destroyed, 2, 'no cyclic references'; 52