The Perl Toolchain Summit 2025 Needs You: You can help 🙏 Learn more

use strict; use warnings;
use Memoize;
use Test::More tests => 11;
sub n_null { '' }
{ my $I = 0;
sub n_diff { $I++ }
}
{ my $I = 0;
sub a1 { $I++; "$_[0]-$I" }
my $J = 0;
sub a2 { $J++; "$_[0]-$J" }
my $K = 0;
sub a3 { $K++; "$_[0]-$K" }
}
my $a_normal = memoize('a1', INSTALL => undef);
my $a_nomemo = memoize('a2', INSTALL => undef, NORMALIZER => 'n_diff');
my $a_allmemo = memoize('a3', INSTALL => undef, NORMALIZER => 'n_null');
my @ARGS;
@ARGS = (1, 2, 3, 2, 1);
is_deeply [map $a_normal->($_), @ARGS], [qw(1-1 2-2 3-3 2-2 1-1)], 'no normalizer';
is_deeply [map $a_nomemo->($_), @ARGS], [qw(1-1 2-2 3-3 2-4 1-5)], 'n_diff';
is_deeply [map $a_allmemo->($_), @ARGS], [qw(1-1 1-1 1-1 1-1 1-1)], 'n_null';
# Test fully-qualified name and installation
my $COUNT;
$COUNT = 0;
sub parity { $COUNT++; $_[0] % 2 }
sub parnorm { $_[0] % 2 }
memoize('parity', NORMALIZER => 'main::parnorm');
is_deeply [map parity($_), @ARGS], [qw(1 0 1 0 1)], 'parity normalizer';
is $COUNT, 2, '... with the expected number of calls';
# Test normalization with reference to normalizer function
$COUNT = 0;
sub par2 { $COUNT++; $_[0] % 2 }
memoize('par2', NORMALIZER => \&parnorm);
is_deeply [map par2($_), @ARGS], [qw(1 0 1 0 1)], '... also installable by coderef';
is $COUNT, 2, '... still with the expected number of calls';
$COUNT = 0;
sub count_uninitialized { $COUNT += join('', @_) =~ /\AUse of uninitialized value / }
my $war1 = memoize(sub {1}, NORMALIZER => sub {undef});
{ local $SIG{__WARN__} = \&count_uninitialized; $war1->() }
is $COUNT, 0, 'no warning when normalizer returns undef';
# Context propagated correctly to normalizer?
sub n {
my $which = wantarray ? 'list' : 'scalar';
local $Test::Builder::Level = $Test::Builder::Level + 2;
is $_[0], $which, "$which context propagates properly";
}
sub f { 1 }
memoize('f', NORMALIZER => 'n');
my $s = f 'scalar';
my @a = f 'list';
sub args { scalar @_ }
sub null_args { join chr(28), splice @_ }
memoize('args', NORMALIZER => 'null_args');
ok args(1), 'original @_ is protected from normalizer';