File Coverage

blib/lib/Linux/Statm/Tiny/Mite.pm
Criterion Covered Total %
statement 84 127 66.1
branch 11 28 39.2
condition 1 2 50.0
subroutine 19 26 73.0
pod 1 4 25.0
total 116 187 62.0


line stmt bran cond sub pod time code
1 3     3   43 use 5.010001;
  3         7  
2 3     3   13 use strict;
  3         5  
  3         42  
3 3     3   10 use warnings;
  3         6  
  3         86  
4              
5             package Linux::Statm::Tiny::Mite;
6              
7             # NOTE: Since the intention is to ship this file with a project, this file
8             # cannot have any non-core dependencies.
9              
10 3     3   14 use strict;
  3         3  
  3         55  
11 3     3   11 use warnings;
  3         4  
  3         391  
12              
13             sub _is_compiling {
14 3 50   3   11 return $ENV{MITE_COMPILE} ? 1 : 0;
15             }
16              
17             sub _make_has {
18 3     3   7 my ( $class, $caller, $file, $kind ) = @_;
19              
20             return sub {
21 90     90   110 my $names = shift;
22 90 50       166 $names = [$names] unless ref $names;
23 90         226 my %args = @_;
24 90         114 for my $name ( @$names ) {
25 90         110 $name =~ s/^\+//;
26              
27 90         93 my $default = $args{default};
28 90 100       137 if ( ref $default eq 'CODE' ) {
29 3     3   16 no strict 'refs';
  3         5  
  3         168  
30 87         84 ${$caller .'::__'.$name.'_DEFAULT__'} = $default;
  87         255  
31             }
32              
33 90         98 my $builder = $args{builder};
34 90 50       118 if ( ref $builder eq 'CODE' ) {
35 3     3   15 no strict 'refs';
  3         6  
  3         161  
36 0         0 *{"$caller\::_build_$name"} = $builder;
  0         0  
37             }
38              
39 90         88 my $trigger = $args{trigger};
40 90 50       133 if ( ref $trigger eq 'CODE' ) {
41 3     3   14 no strict 'refs';
  3         4  
  3         1807  
42 0         0 *{"$caller\::_trigger_$name"} = $trigger;
  0         0  
43             }
44             }
45              
46 90         183 return;
47 3         12 };
48             }
49              
50             sub import {
51 3     3   7 my ( $class, $kind ) = @_;
52 3         9 my ( $caller, $file ) = caller;
53              
54             # Turn on warnings and strict in the caller
55 3         24 warnings->import;
56 3         9 strict->import;
57              
58 3   50     18 $kind ||= 'class';
59 3 50       10 $kind = ( $kind =~ /role/i ) ? 'role' : 'class';
60              
61 3 50       7 if( _is_compiling() ) {
62 0         0 require Mite::Project;
63 0         0 my $method = "inject_mite_$kind\_functions";
64 0         0 Mite::Project->default->$method(
65             package => $caller,
66             file => $file,
67             );
68             }
69             else {
70             # Work around Test::Compile's tendency to 'use' modules.
71             # Mite.pm won't stand for that.
72 3 50       10 return if $ENV{TEST_COMPILE};
73              
74             # Changes to this filename must be coordinated with Mite::Compiled
75 3         6 my $mite_file = $file . ".mite.pm";
76 3 50       46 if( !-e $mite_file ) {
77 0         0 require Carp;
78 0         0 Carp::croak("Compiled Mite file ($mite_file) for $file is missing");
79             }
80              
81             {
82 3         7 local @INC = ('.', @INC);
  3         13  
83 3         1077 require $mite_file;
84             }
85              
86 3         13 my $method = "_inject_mite_$kind\_functions";
87 3         19 $class->$method( $caller, $file );
88             }
89             }
90              
91             my $parse_mm_args = sub {
92             my $coderef = pop;
93             my $names = [ map { ref($_) ? @$_ : $_ } @_ ];
94             ( $names, $coderef );
95             };
96              
97             {
98             my $get_orig = sub {
99             my ( $caller, $name ) = @_;
100             \&{ "$caller\::$name" };
101             };
102              
103             sub before {
104 0     0 0 0 my ( $me, $caller ) = ( shift, shift );
105 0         0 my ( $names, $coderef ) = &$parse_mm_args;
106 0         0 for my $name ( @$names ) {
107 0         0 my $orig = $get_orig->( $caller, $name );
108 0         0 local $@;
109 0 0       0 eval <<"BEFORE" or die $@;
110             package $caller;
111             no warnings 'redefine';
112             sub $name {
113             \$coderef->( \@_ );
114             \$orig->( \@_ );
115             }
116             1;
117             BEFORE
118             }
119 0         0 return;
120             }
121              
122             sub after {
123 0     0 0 0 my ( $me, $caller ) = ( shift, shift );
124 0         0 my ( $names, $coderef ) = &$parse_mm_args;
125 0         0 for my $name ( @$names ) {
126 0         0 my $orig = $get_orig->( $caller, $name );
127 0         0 local $@;
128 0 0       0 eval <<"AFTER" or die $@;
129             package $caller;
130             no warnings 'redefine';
131             sub $name {
132             my \@r;
133             if ( wantarray ) {
134             \@r = \$orig->( \@_ );
135             }
136             elsif ( defined wantarray ) {
137             \@r = scalar \$orig->( \@_ );
138             }
139             else {
140             \$orig->( \@_ );
141             1;
142             }
143             \$coderef->( \@_ );
144             wantarray ? \@r : \$r[0];
145             }
146             1;
147             AFTER
148             }
149 0         0 return;
150             }
151              
152             sub around {
153 3     3 0 6 my ( $me, $caller ) = ( shift, shift );
154 3         9 my ( $names, $coderef ) = &$parse_mm_args;
155 3         7 for my $name ( @$names ) {
156 3         8 my $orig = $get_orig->( $caller, $name );
157 3         6 local $@;
158 3 50   3 1 17 eval <<"AROUND" or die $@;
  3     1   6  
  3         135  
  3         234  
  1         12  
159             package $caller;
160             no warnings 'redefine';
161             sub $name {
162             \$coderef->( \$orig, \@_ );
163             }
164             1;
165             AROUND
166             }
167 3         7 return;
168             }
169             }
170              
171              
172             sub _inject_mite_class_functions {
173 3     3   8 my ( $class, $caller, $file ) = ( shift, @_ );
174              
175 3     3   19 no strict 'refs';
  3         6  
  3         522  
176 3         9 *{ $caller .'::has' } = $class->_make_has( $caller, $file, 'class' );
  3         13  
177 3         10 *{ $caller .'::with' } = sub {
178 0     0   0 while ( @_ ) {
179 0         0 my $role = shift;
180 0 0       0 my $args = ref($_[0]) ? shift : undef;
181 0         0 $role->__FINALIZE_APPLICATION__( $caller, $args );
182             }
183 3         9 };
184 3     0   6 *{ $caller .'::extends'} = sub {};
  3         10  
185 3         6 for my $mm ( qw/ before after around / ) {
186 9         119 *{"$caller\::$mm"} = sub {
187 3     3   29 $class->$mm( $caller, @_ );
188 3         6 return;
189 9         20 };
190             }
191             }
192              
193             sub _inject_mite_role_functions {
194 0     0     my ( $class, $caller, $file ) = ( shift, @_ );
195              
196 3     3   18 no strict 'refs';
  3         4  
  3         556  
197 0           *{ $caller .'::has' } = $class->_make_has( $caller, $file, 'role' );
  0            
198 0           *{ $caller .'::with' } = sub {
199 0     0     while ( @_ ) {
200 0           my $role = shift;
201 0 0         my $args = ref($_[0]) ? shift : undef;
202 0           $role->__FINALIZE_APPLICATION__( $caller, $args );
203             }
204 0           };
205              
206 0           my $MM = \@{"$caller\::METHOD_MODIFIERS"};
  0            
207 0           for my $modifier ( qw/ before after around / ) {
208 0           *{ $caller .'::'. $modifier } = sub {
209 0     0     my ( $names, $coderef ) = &$parse_mm_args;
210 0           push @$MM, [ $modifier, $names, $coderef ];
211 0           };
212             }
213             }
214              
215             1;
216              
217             __END__