File Coverage

blib/lib/MooX/PluginKit/Factory.pm
Criterion Covered Total %
statement 37 38 97.3
branch 2 4 50.0
condition 0 3 0.0
subroutine 11 11 100.0
pod 2 2 100.0
total 52 58 89.6


line stmt bran cond sub pod time code
1             package MooX::PluginKit::Factory;
2 3     3   48 use 5.008001;
  3         9  
3 3     3   16 use strictures 2;
  3         14  
  3         87  
4             our $VERSION = '0.06';
5              
6             =head1 NAME
7              
8             MooX::PluginKit::Factory - Dynamically apply plugins to classes at runtime.
9              
10             =head1 SYNOPSIS
11              
12             use MooX::PluginKit::Factory;
13            
14             my $kit = MooX::PluginKit::Factory->new(
15             plugins => [...],
16             namespace => ...,
17             );
18            
19             my $object = $kit->class_new('Some::Class', %args);
20              
21             =head1 DESCRIPTION
22              
23             A PluginKit factory takes a list of plugins and then provides methods
24             for applying those plugins to classes and building objects from those classes.
25              
26             Unless you are a power user you are better off using
27             L.
28              
29             =cut
30              
31 3     3   493 use MooX::PluginKit::Core;
  3         5  
  3         295  
32 3     3   1455 use Types::Standard -types;
  3         194440  
  3         32  
33 3     3   13884 use Types::Common::String -types;
  3         60295  
  3         45  
34 3     3   4268 use Module::Runtime qw( require_module );
  3         7  
  3         24  
35              
36 3     3   141 use Moo;
  3         18  
  3         26  
37 3     3   1437 use namespace::clean;
  3         5  
  3         30  
38              
39             =head1 ARGUMENTS
40              
41             =head2 plugins
42              
43             An array ref of plugin names (relative or absolute).
44              
45             =cut
46              
47             has plugins => (
48             is => 'ro',
49             isa => ArrayRef[ NonEmptySimpleStr ],
50             default => sub{ [] },
51             );
52              
53             =head2 namespace
54              
55             The namespace to resolve relative plugin names to.
56              
57             =cut
58              
59             has namespace => (
60             is => 'ro',
61             isa => NonEmptySimpleStr,
62             );
63              
64             =head1 ATTRIBUTES
65              
66             =head2 resolved_plugins
67              
68             L with all relative plugin names resolved.
69              
70             =cut
71              
72             has resolved_plugins => (
73             is => 'lazy',
74             init_arg => undef,
75             );
76             sub _build_resolved_plugins {
77 28     28   217 my ($self) = @_;
78              
79             return [
80 12         85 map { resolve_plugin( $_, $self->namespace() ) }
81 28         44 @{ $self->plugins() }
  28         133  
82             ];
83             }
84              
85             =head1 METHODS
86              
87             =head2 build_class
88              
89             my $new_class = $kit->build_class( $class );
90              
91             Creates a new class with all applicable L applied to it
92             and returns the new class name.
93              
94             =cut
95              
96             sub build_class {
97 29     29 1 95 my ($self, $base_class) = @_;
98              
99             return build_class_with_plugins(
100             $base_class,
101 29         54 @{ $self->resolved_plugins() },
  29         489  
102             );
103             }
104              
105             =head2 class_new
106              
107             my $object = $kit->class_new( $class, %args );
108              
109             Calls L and then creates an object of that class.
110             If the class to be built is a plugin consumer then
111             L will be defaulted
112             to this factory.
113              
114             =cut
115              
116             sub class_new {
117 11     11 1 18 my $self = shift;
118 11         18 my $base_class = shift;
119              
120 11         25 my $class = $self->build_class( $base_class );
121 11 50       3679 require_module $class if !$class->can('new');
122 11         62 my $args = $class->BUILDARGS( @_ );
123              
124 11 50       108 if (is_consumer $class) {
125 0   0     0 $args->{plugin_factory} ||= $self;
126             }
127              
128 11         35 return $class->new( $args );
129             }
130              
131             1;
132             __END__