File Coverage

blib/lib/Evo/Attr.pm
Criterion Covered Total %
statement 51 51 100.0
branch 11 18 61.1
condition 2 2 100.0
subroutine 10 10 100.0
pod 0 4 0.0
total 74 85 87.0


line stmt bran cond sub pod time code
1             package Evo::Attr;
2 67     67   449 use strict;
  67         148  
  67         1949  
3 67     67   369 use warnings;
  67         160  
  67         1944  
4 67     67   386 use Carp 'croak';
  67         149  
  67         6142  
5 67     67   29736 use Evo::Internal::Util;
  67         240  
  67         2345  
6 67     67   455 use feature 'signatures';
  67         154  
  67         4615  
7 67     67   429 no warnings 'experimental::signatures';
  67         141  
  67         34926  
8              
9             my $MCO = \&invoke_handlers;
10              
11 844 50   844 0 3078 sub patch_package ($me, $pkg) {
  844 50       2465  
  844         1705  
  844         1500  
  844         1455  
12 844         3638 Evo::Internal::Util::monkey_patch $pkg, MODIFY_CODE_ATTRIBUTES => $MCO;
13             }
14              
15             our %HANDLERS;
16              
17             %HANDLERS = (
18             Attr => {
19             provider => __PACKAGE__,
20             handler => sub ($provider, $handler, $name) {
21             register_attribute($provider, $name, $handler);
22             }
23             }
24             );
25              
26             # $provider is a key, just for error message
27 189 50   189 0 2220 sub register_attribute ($provider, $name, $handler) {
  189 50       545  
  189         363  
  189         334  
  189         324  
  189         324  
28 189 100       691 croak "$name was already taken by $HANDLERS{$name}{provider}" if $HANDLERS{$name};
29 188         984 $HANDLERS{$name} = {provider => $provider, handler => $handler};
30             }
31              
32 1311 50   1311 0 58171 sub invoke_handlers ($dest, $code, @attrs) {
  1311         2542  
  1311         2277  
  1311         3955  
  1311         2276  
33 1311         4148 my (undef, $subname) = Evo::Internal::Util::code2names($code);
34 1311         2676 my @remaining;
35 1311         3122 foreach my $attr_raw (@attrs) {
36 1320         3209 my ($attr, @args) = parse_attr($attr_raw);
37              
38 1320 100       4439 if (my $slot = $HANDLERS{$attr}) {
39 1314         4532 $slot->{handler}->($dest, $code, $subname, @args);
40             }
41 6         18 else { push @remaining, $attr_raw }
42             }
43 1311         4212 @remaining;
44             }
45              
46 1324 50   1324 0 4340 sub parse_attr ($attr) {
  1324 50       3170  
  1324         2262  
  1324         2037  
47 1324         7009 $attr =~ /(\w+) ( \( \s* ([\w\,\s]+) \s* \) )?/x;
48 1324   100     11178 return ($1, split /\,\s?/, $3 // '');
49             }
50              
51             1;
52              
53             __END__