File Coverage

blib/lib/Sub/HandlesVia/Mite.pm
Criterion Covered Total %
statement 64 153 41.8
branch 18 62 29.0
condition 1 19 5.2
subroutine 15 26 57.6
pod 0 9 0.0
total 98 269 36.4


line stmt bran cond sub pod time code
1             # NOTE: Since the intention is to ship this file with a project, this file
2             # cannot have any non-core dependencies.
3             use 5.008001;
4 94     94   1573 use strict;
  94         385  
5 94     94   537 use warnings;
  94         210  
  94         2133  
6 94     94   548 no strict 'refs';
  94         231  
  94         3034  
7 94     94   672  
  94         367  
  94         30966  
8             if ( $] < 5.009005 ) { require MRO::Compat; }
9             else { require mro; }
10              
11             defined ${^GLOBAL_PHASE}
12             or eval { require Devel::GlobalDestruction; 1 }
13             or do {
14             carp( "WARNING: Devel::GlobalDestruction recommended!" );
15             *Devel::GlobalDestruction::in_global_destruction = sub { undef; };
16             };
17              
18             # Constants
19              
20             # More complicated constants
21             BEGIN {
22             my @bool = ( \&false, \&true );
23             *_HAS_AUTOCLEAN = $bool[ 0+!! eval { require namespace::autoclean } ];
24             *STRICT = $bool[ 0+!! ( $ENV{PERL_STRICT} || $ENV{EXTENDED_TESTING} || $ENV{AUTHOR_TESTING} || $ENV{RELEASE_TESTING} ) ];
25             };
26              
27             # Exportable error handlers
28             my ( $func, $message, @args ) = @_;
29             if ( @args ) {
30 94     94   616 require Data::Dumper;
31 94         312 local $Data::Dumper::Terse = 1;
  94         40165  
32 94   0     1342474 local $Data::Dumper::Indent = 0;
33             $message = sprintf $message, map {
34             ref($_) ? Data::Dumper::Dumper($_) : defined($_) ? $_ : '(undef)'
35             } @args;
36             }
37 0     0   0 my $next = do { require Carp; \&{"Carp::$func"} };
38 0 0       0 @_ = ( $message );
39 0         0 goto $next;
40 0         0 }
41 0         0  
42              
43 0 0       0 # Exportable guard function
  0 0       0  
44             {
45             my $GUARD_PACKAGE = __PACKAGE__ . '::Guard';
46 0         0 *{"$GUARD_PACKAGE\::DESTROY"} = sub { $_[0][0] or $_[0][1]->() };
  0         0  
  0         0  
  0         0  
47 0         0 *{"$GUARD_PACKAGE\::restore"} = sub { $_[0]->DESTROY; $_[0][0] = true };
48 0         0 *{"$GUARD_PACKAGE\::dismiss"} = sub { $_[0][0] = true };
49             *{"$GUARD_PACKAGE\::peek"} = sub { $_[0][2] };
50             *guard = sub (&) { bless [ 0, @_ ] => $GUARD_PACKAGE };
51 0     0 0 0 }
  0         0  
52 0     0 0 0  
  0         0  
53 0     0 0 0 defined $Mite::COMPILING and $Mite::COMPILING eq __PACKAGE__;
  0         0  
54             }
55              
56             my $me = shift;
57             my %arg = map { lc($_) => true } @_;
58 12744 50   12744   41875 my ( $caller, $file ) = caller;
59 0     0   0  
  0         0  
60 0     0   0 if( _is_compiling() ) {
61 0     0   0 require Mite::Project;
62 12744     12744   43126 Mite::Project->default->inject_mite_functions(
63             package => $caller,
64             file => $file,
65             arg => \%arg,
66 558 50   558   2882 shim => $me,
67             );
68             }
69             else {
70 558     558   1647 # Changes to this filename must be coordinated with Mite::Compiled
71 558         1615 my $mite_file = $file . ".mite.pm";
  385         2538  
72 558         2735 if( !-e $mite_file ) {
73             croak "Compiled Mite file ($mite_file) for $file is missing";
74 558 50       1863 }
75 0         0  
76 0         0 {
77             local @INC = ('.', @INC);
78             require $mite_file;
79             }
80             }
81              
82             warnings->import;
83             strict->import;
84             'namespace::autoclean'->import( -cleanee => $caller )
85 558         1642 if _HAS_AUTOCLEAN && !$arg{'-unclean'};
86 558 50       11668 }
87 0         0  
88             {
89             my ( $cb_before, $cb_after );
90             my ( $me, $role, $caller, $args ) = @_;
91 558         1620 if ( $INC{'Role/Hooks.pm'} ) {
  558         4029  
92 558         193867 $cb_before ||= \%Role::Hooks::CALLBACKS_BEFORE_APPLY;
93             $cb_after ||= \%Role::Hooks::CALLBACKS_AFTER_APPLY;
94             }
95             if ( $cb_before ) {
96 558         8209 $_->( $role, $caller ) for @{ $cb_before->{$role} || [] };
97 558         2762 }
98             'Role::Tiny'->_check_requires( $caller, $role );
99 558 50       4770 my $info = $Role::Tiny::INFO{$role};
100             for ( @{ $info->{modifiers} || [] } ) {
101             my @args = @$_;
102             my $modification = shift @args;
103             my $handler = "HANDLE_$modification";
104             $me->$handler( $caller, undef, @args );
105 0     0   0 }
106 0 0       0 if ( $cb_after ) {
107 0   0     0 $_->( $role, $caller ) for @{ $cb_after->{$role} || [] };
108 0   0     0 }
109             return;
110 0 0       0 }
111 0 0       0  
  0         0  
112             # Usage: $me, $caller, @with_args
113 0         0 my ( $me, $caller ) = ( shift, shift );
114 0         0 while ( @_ ) {
115 0 0       0 my $role = shift;
  0         0  
116 0         0 my $args = ref($_[0]) ? shift : undef;
117 0         0 if ( $INC{'Role/Tiny.pm'} and 'Role::Tiny'->is_role( $role ) ) {
118 0         0 $me->_finalize_application_roletiny( $role, $caller, $args );
119 0         0 }
120             else {
121 0 0       0 $role->__FINALIZE_APPLICATION__( $caller, $args );
122 0 0       0 }
  0         0  
123             }
124 0         0 return;
125             }
126             }
127              
128             # Usage: $me, $caller, $keyword, @has_args
129 0     0 0 0 my ( $me, $caller, $keyword, $names ) = ( shift, shift, shift, shift );
130 0         0 if ( @_ % 2 ) {
131 0         0 my $default = shift;
132 0 0       0 unshift @_, ( 'CODE' eq ref( $default ) )
133 0 0 0     0 ? ( is => lazy, builder => $default )
134 0         0 : ( is => ro, default => $default );
135             }
136             my %spec = @_;
137 0         0 my $code;
138             for my $name ( ref($names) ? @$names : $names ) {
139             $name =~ s/^\+//;
140 0         0 'CODE' eq ref( $code = $spec{default} )
141             and ${"$caller\::__$name\_DEFAULT__"} = $code;
142             'CODE' eq ref( $code = $spec{builder} )
143             and *{"$caller\::_build_$name"} = $code;
144             'CODE' eq ref( $code = $spec{trigger} )
145             and *{"$caller\::_trigger_$name"} = $code;
146 3900     3900 0 9060 'CODE' eq ref( $code = $spec{clone} )
147 3900 50       7891 and *{"$caller\::_clone_$name"} = $code;
148 0         0 }
149 0 0       0 return;
150             }
151              
152             {
153 3900         9797 my $_kind = sub { ${ shift() . '::USES_MITE' } =~ /Role/ ? 'role' : 'class' };
154 3900         5408  
155 3900 100       7771 my ( $caller, $name ) = @_;
156 4364         6924 my $orig = $caller->can( $name );
157             return $orig if $orig;
158 4364 100       9194 croak "Cannot modify method $name in $caller: no such method";
  94         612  
159             }
160 4364 100       8958  
  1016         5654  
161             my $coderef = pop;
162 4364 50       9891 my $names = [ map { ref($_) ? @$_ : $_ } @_ ];
  0         0  
163             ( $names, $coderef );
164 4364 50       9123 }
  0         0  
165              
166 3900         9203 # Usage: $me, $caller, $caller_kind, @before_args
167             my ( $me, $caller, $kind ) = ( shift, shift, shift );
168             my ( $names, $coderef ) = &_parse_mm_args;
169             $kind ||= $caller->$_kind;
170             if ( $kind eq 'role' ) {
171             push @{"$caller\::METHOD_MODIFIERS"},
172             [ before => $names, $coderef ];
173 1     1   3 return;
174 1         9 }
175 1 50       5 for my $name ( @$names ) {
176 0         0 my $orig = _get_orig_method( $caller, $name );
177             local $@;
178             eval <<"BEFORE" or die $@;
179             package $caller;
180 1     1   4 no warnings 'redefine';
181 1 50       3 sub $name {
  1         6  
182 1         4 \$coderef->( \@_ );
183             \$orig->( \@_ );
184             }
185             1;
186             BEFORE
187 0     0 0 0 }
188 0         0 return;
189 0   0     0 }
190 0 0       0  
191 0         0 # Usage: $me, $caller, $caller_kind, @after_args
  0         0  
192             my ( $me, $caller, $kind ) = ( shift, shift, shift );
193 0         0 my ( $names, $coderef ) = &_parse_mm_args;
194             $kind ||= $caller->$_kind;
195 0         0 if ( $kind eq 'role' ) {
196 0         0 push @{"$caller\::METHOD_MODIFIERS"},
197 0         0 [ after => $names, $coderef ];
198 0 0       0 return;
199             }
200             for my $name ( @$names ) {
201             my $orig = _get_orig_method( $caller, $name );
202             local $@;
203             eval <<"AFTER" or die $@;
204             package $caller;
205             no warnings 'redefine';
206             sub $name {
207             my \@r;
208 0         0 if ( wantarray ) {
209             \@r = \$orig->( \@_ );
210             }
211             elsif ( defined wantarray ) {
212             \@r = scalar \$orig->( \@_ );
213 0     0 0 0 }
214 0         0 else {
215 0   0     0 \$orig->( \@_ );
216 0 0       0 1;
217 0         0 }
  0         0  
218             \$coderef->( \@_ );
219 0         0 wantarray ? \@r : \$r[0];
220             }
221 0         0 1;
222 0         0 AFTER
223 0         0 }
224 0 0       0 return;
225             }
226              
227             # Usage: $me, $caller, $caller_kind, @around_args
228             my ( $me, $caller, $kind ) = ( shift, shift, shift );
229             my ( $names, $coderef ) = &_parse_mm_args;
230             $kind ||= $caller->$_kind;
231             if ( $kind eq 'role' ) {
232             push @{"$caller\::METHOD_MODIFIERS"},
233             [ around => $names, $coderef ];
234             return;
235             }
236             for my $name ( @$names ) {
237             my $orig = _get_orig_method( $caller, $name );
238             local $@;
239             eval <<"AROUND" or die $@;
240             package $caller;
241             no warnings 'redefine';
242             sub $name {
243             \$coderef->( \$orig, \@_ );
244             }
245 0         0 1;
246             AROUND
247             }
248             return;
249             }
250 1     1 0 4 }
251 1         4  
252 1   33     6 # Usage: $me, $caller, $caller_kind, @signature_for_args
253 1 50       15 my ( $me, $caller, $kind, $name ) = @_;
254 0         0 $name =~ s/^\+//;
  0         0  
255             $me->HANDLE_around( $caller, $kind, $name, ${"$caller\::SIGNATURE_FOR"}{$name} );
256 0         0 return;
257             }
258 1         3  
259 1         4 1;