Skip to content

Instantly share code, notes, and snippets.

@tommybutler
Last active August 16, 2018 11:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tommybutler/40e02dd713bb6a5fbb347649556ba2d4 to your computer and use it in GitHub Desktop.
Save tommybutler/40e02dd713bb6a5fbb347649556ba2d4 to your computer and use it in GitHub Desktop.
Proxy an entire class in Perl OOP, in order to memo-ize method calls
use strict;
use warnings;
package My::Class::Proxy; # Drop-in replacement for 'Some Class'
# Proxies all public method calls to Some::Class in order to provide smart
# caching and memoization, e.g.- avoiding expensive DB queries when not required
use 5.020;
use Moose;
use lib 'lib';
extends 'Some::Class';
use Moose::Util qw();
my $meta = Moose::Util::find_meta( 'Some::Class' );
my @nocache = qw( new meta DESTROY AUTOLOAD );
state $outputs = {};
for my $method ( $meta->get_method_list )
{
# don't memo-ize blaclisted or private methods
next if ( grep { $_ eq $method } @nocache or $method =~ /^_/ );
around $method => sub
{
my ( $orig, $self, $refresh, @args ) = @_;
$outputs = {} if !!$refresh;
@args = map { $_ // '' } @args;
my $call_key = join '', $orig, @args;
return $outputs->{ $call_key } if defined $outputs->{ $call_key };
$outputs->{ $call_key } = $self->$orig( @args );
return $outputs->{ $call_key };
};
}
# Moose-specific optimization
__PACKAGE__->meta->make_immutable();
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment