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   437 use strict;
  67         148  
  67         1827  
3 67     67   470 use warnings;
  67         145  
  67         1762  
4 67     67   358 use Carp 'croak';
  67         145  
  67         3166  
5 67     67   24828 use Evo::Internal::Util;
  67         207  
  67         2399  
6 67     67   488 use feature 'signatures';
  67         149  
  67         4268  
7 67     67   479 no warnings 'experimental::signatures';
  67         143  
  67         36123  
8              
9             my $MCO = \&invoke_handlers;
10              
11 844 50   844 0 3012 sub patch_package ($me, $pkg) {
  844 50       2376  
  844         1817  
  844         1389  
  844         1458  
12 844         3647 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 2006 sub register_attribute ($provider, $name, $handler) {
  189 50       525  
  189         369  
  189         316  
  189         313  
  189         297  
28 189 100       714 croak "$name was already taken by $HANDLERS{$name}{provider}" if $HANDLERS{$name};
29 188         956 $HANDLERS{$name} = {provider => $provider, handler => $handler};
30             }
31              
32 1311 50   1311 0 55523 sub invoke_handlers ($dest, $code, @attrs) {
  1311         2432  
  1311         2229  
  1311         3843  
  1311         2312  
33 1311         4039 my (undef, $subname) = Evo::Internal::Util::code2names($code);
34 1311         2696 my @remaining;
35 1311         2751 foreach my $attr_raw (@attrs) {
36 1320         3165 my ($attr, @args) = parse_attr($attr_raw);
37              
38 1320 100       4248 if (my $slot = $HANDLERS{$attr}) {
39 1314         4497 $slot->{handler}->($dest, $code, $subname, @args);
40             }
41 6         17 else { push @remaining, $attr_raw }
42             }
43 1311         4175 @remaining;
44             }
45              
46 1324 50   1324 0 4098 sub parse_attr ($attr) {
  1324 50       3101  
  1324         2275  
  1324         1945  
47 1324         6732 $attr =~ /(\w+) ( \( \s* ([\w\,\s]+) \s* \) )?/x;
48 1324   100     10668 return ($1, split /\,\s?/, $3 // '');
49             }
50              
51             1;
52              
53             __END__