1package Bread::Board::LifeCycle::Singleton::WithParameters; 2our $AUTHORITY = 'cpan:STEVAN'; 3# ABSTRACT: singleton lifecycle role for a parameterized service 4$Bread::Board::LifeCycle::Singleton::WithParameters::VERSION = '0.37'; 5use Moose::Role; 6 7with 'Bread::Board::LifeCycle'; 8 9has 'instances' => ( 10 traits => [ 'Hash', 'NoClone' ], 11 is => 'rw', 12 isa => 'HashRef', 13 lazy => 1, 14 default => sub { +{} }, 15 clearer => 'flush_instances', 16 handles => { 17 'has_instance_at_key' => 'exists', 18 'get_instance_at_key' => 'get', 19 'set_instance_at_key' => 'set', 20 } 21); 22 23around 'get' => sub { 24 my $next = shift; 25 my $self = shift; 26 my $key = $self->generate_instance_key(@_); 27 28 # return it if we got it ... 29 return $self->get_instance_at_key($key) 30 if $self->has_instance_at_key($key); 31 32 # otherwise fetch it ... 33 my $instance = $self->$next(@_); 34 35 # if we get a copy, and our copy 36 # has not already been set ... 37 $self->set_instance_at_key($key => $instance) 38 unless $self->has_instance_at_key($key); 39 40 # return whatever we have ... 41 return $self->get_instance_at_key($key); 42}; 43 44sub generate_instance_key { 45 my ($self, @args) = @_; 46 return "$self" unless @args; 47 return join "|" => sort map { "$_" } @args 48} 49 50no Moose::Role; 1; 51 52__END__ 53 54=pod 55 56=encoding UTF-8 57 58=head1 NAME 59 60Bread::Board::LifeCycle::Singleton::WithParameters - singleton lifecycle role for a parameterized service 61 62=head1 VERSION 63 64version 0.37 65 66=head1 DESCRIPTION 67 68Sub-role of L<Bread::Board::LifeCycle>, this role defines the 69"singleton" lifecycle for a parameterized service. The C<get> method 70will only do its work the first time it is invoked for each set of 71parameters; subsequent invocations with the same parameters will 72return the same object. 73 74=head1 ATTRIBUTES 75 76=head2 C<instances> 77 78Hashref mapping keys to objects, used to cache the results of L</get> 79 80=head1 METHODS 81 82=head2 C<get> 83 84Generates a key using L</generate_instance_key> (passing it all the 85arguments); if the L</instances> attribute does not hold an object for 86that key, it will build it (by calling the underlying C<get> method) 87and store it in L</instances>. The object (either retrieved from 88L</instances> or freshly built) will be returned. 89 90=head2 C<generate_instance_key> 91 92Generates a (hopefully) unique key from the given arguments (usually, 93whatever was passed to L</get>). The current implementation 94stringifies all arguments, so different references to identical values 95will be considered different. 96 97=head1 AUTHOR 98 99Stevan Little <stevan@iinteractive.com> 100 101=head1 BUGS 102 103Please report any bugs or feature requests on the bugtracker website 104https://github.com/stevan/BreadBoard/issues 105 106When submitting a bug or request, please include a test-file or a 107patch to an existing test-file that illustrates the bug or desired 108feature. 109 110=head1 COPYRIGHT AND LICENSE 111 112This software is copyright (c) 2019, 2017, 2016, 2015, 2014, 2013, 2011, 2009 by Infinity Interactive. 113 114This is free software; you can redistribute it and/or modify it under 115the same terms as the Perl 5 programming language system itself. 116 117=cut 118