File Coverage

blib/lib/MooX/Roles/Pluggable.pm
Criterion Covered Total %
statement 32 32 100.0
branch 6 6 100.0
condition n/a
subroutine 7 7 100.0
pod n/a
total 45 45 100.0


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