File Coverage

blib/lib/MooX/Roles/Pluggable.pm
Criterion Covered Total %
statement 38 39 97.4
branch 4 6 66.6
condition n/a
subroutine 9 9 100.0
pod n/a
total 51 54 94.4


line stmt bran cond sub pod time code
1             package MooX::Roles::Pluggable;
2              
3 3     3   377589 use 5.008003;
  3         12  
  3         136  
4 3     3   18 use strict;
  3         5  
  3         114  
5 3     3   16 use warnings FATAL => 'all';
  3         10  
  3         304  
6              
7             require Module::Pluggable::Object;
8              
9             our $VERSION = '0.002';
10              
11             my %DEFAULT_OPTIONS = (
12             search_path => undef,
13             require => 1,
14             );
15              
16             my %role_lists;
17              
18 3     3   3704 use Data::Dumper;
  3         35491  
  3         478  
19              
20             sub _roles
21             {
22 0         0 defined( $role_lists{ $_[0]->{search_path} } )
23 1 50   1   7 and return @{ $role_lists{ $_[0]->{search_path} } };
24 1         3 my @plugins = Module::Pluggable::Object->new( %{ $_[0] } )->plugins();
  1         9  
25 2         5 my @roles = grep {
26 1         39860 my @target_isa;
27 3     3   27 { no strict 'refs'; @target_isa = @{ $_ . "::ISA" } };
  3         8  
  3         917  
  2         3  
  2         4  
  2         8  
28 2         6 0 == scalar @target_isa;
29             } @plugins;
30 1         7 $role_lists{ $_[0]->{search_path} } = \@roles;
31             }
32              
33             sub _inject_roles
34             {
35 3     3   10 my ( $target, $options ) = @_;
36 3 100       57 my $with = $target->can('with') or return; # neither a class nor a role ...
37 1         18 my $roles = _roles($options);
38              
39             my $apply_modifiers = sub {
40 1     1   3 foreach my $role (@$roles)
41             {
42 2         106569 $with->($role);
43             }
44 1         7 };
45 1         3 $apply_modifiers->();
46             }
47              
48             sub import
49             {
50 3     3   48 my ( undef, @import ) = @_;
51 3         13 my $target = caller;
52 3         16 my %options = ( %DEFAULT_OPTIONS, @import );
53 3 50       32 defined( $options{search_path} ) or $options{search_path} = "${target}::Role";
54              
55 3         17 _inject_roles( $target, \%options );
56              
57 3         4899 return;
58             }
59              
60             =head1 NAME
61              
62             MooX::Roles::Pluggable - Moo eXtension for pluggable roles
63              
64             =head1 SYNOPSIS
65              
66             package MyPackage;
67              
68             use Moo;
69              
70             sub foo { ... }
71              
72             use MooX::Roles::Pluggable search_path => 'MyPackage::Role';
73              
74             package MyPackage::Role::Bar;
75              
76             use Moo::Role;
77              
78             around foo => sub {
79             ...
80             };
81              
82             1;
83              
84             =head1 DESCRIPTION
85              
86             This module allows a class consuming several roles based on rules passed
87             to L.
88              
89             The basic idea behind this tool is the ability to have plugins as roles
90             which attach themselve using the C, C and C sugar
91             of I.
92              
93             The arguments of import are redirected to L,
94             with following defaults (unless specified):
95              
96             =over 4
97              
98             =item C
99              
100             Default search_path is C<< ${caller}::Role >>.
101              
102             =item C
103              
104             Default for require is 1.
105              
106             =back
107              
108             =head2 USE WITH CAUTION
109              
110             Remember that using a module like this which automatically injects code
111             into your existing and running and (hopefully) well tested programs
112             and/or modules can be dangerous and should be avoided whenever possible.
113              
114             =head2 USE ANYWAY
115              
116             On the other hand, when you're allowing plugins being loaded by your
117             code, it's probably faster compiling the chain of responsibility once than
118             doing it at runtime again and again. Allowing plugins changing the
119             behaviour of your code anyway. When that's the intension, this is your
120             module.
121              
122             =head1 AUTHOR
123              
124             Jens Rehsack, C<< >>
125              
126             =head1 BUGS
127              
128             Please report any bugs or feature requests to
129             C, or through the web interface at
130             L.
131             I will be notified, and then you'll automatically be notified of progress
132             on your bug as I make changes.
133              
134             =head1 SUPPORT
135              
136             You can find documentation for this module with the perldoc command.
137              
138             perldoc MooX::Roles::Pluggable
139              
140             You can also look for information at:
141              
142             =over 4
143              
144             =item * RT: CPAN's request tracker (report bugs here)
145              
146             L
147              
148             =item * AnnoCPAN: Annotated CPAN documentation
149              
150             L
151              
152             =item * CPAN Ratings
153              
154             L
155              
156             =item * Search CPAN
157              
158             L
159              
160             =back
161              
162             =head1 ACKNOWLEDGEMENTS
163              
164              
165             =head1 LICENSE AND COPYRIGHT
166              
167             Copyright 2013 Jens Rehsack.
168              
169             This program is free software; you can redistribute it and/or modify it
170             under the terms of either: the GNU General Public License as published
171             by the Free Software Foundation; or the Artistic License.
172              
173             See L for more information.
174              
175             =cut
176              
177             1; # End of MooX::Roles::Pluggable