File Coverage

blib/lib/Sub/Talisman.pm
Criterion Covered Total %
statement 88 91 96.7
branch 7 12 58.3
condition n/a
subroutine 25 26 96.1
pod 4 4 100.0
total 124 133 93.2


line stmt bran cond sub pod time code
1             package Sub::Talisman;
2              
3 1     1   15568 use 5.008;
  1         3  
4 1     1   5 use strict;
  1         2  
  1         20  
5 1     1   5 use warnings;
  1         4  
  1         39  
6              
7             BEGIN {
8 1     1   3 $Sub::Talisman::AUTHORITY = 'cpan:TOBYINK';
9 1         12 $Sub::Talisman::VERSION = '0.006';
10             }
11              
12 1     1   444 use Attribute::Handlers;
  1         2343  
  1         5  
13 1     1   30 use Scalar::Util qw( refaddr );
  1         1  
  1         83  
14 1     1   396 use Sub::Util qw( subname set_subname );
  1         248  
  1         205  
15              
16             sub _identify
17             {
18             my $sub = shift;
19             if (ref $sub)
20             {
21             my ($p, $n) = subname($sub) =~ m/\A(.*)::([^:]+)\z/;
22             $n .= sprintf('(%d)', refaddr($sub)) if $n eq '__ANON__';
23             return ($p, $n);
24             }
25             elsif ($sub =~ /::/)
26             {
27             my ($p, $n) = ($sub =~ /^(.*)::(\w+)$/);
28             $p = 'main' if $p eq q();
29             return ($p, $n);
30             }
31             else
32             {
33             return ($_[0], $sub);
34             }
35             }
36              
37 1     1   382 use namespace::clean;
  1         11573  
  1         5  
38             my (%TALI, %FETCH);
39              
40             sub setup_for
41             {
42 4     4 1 13 my ($class, $caller, $opts) = @_;
43 4         11 my $atr = $opts->{attribute};
44 1     1   9 eval qq{
  1     1   8  
  1     1   8  
  0     1   0  
  0     0   0  
  0     3   0  
  1     2   14  
  1     2   3  
  1         4  
  3         3964  
  3         24  
  3         16  
  1         9  
  1         3  
  1         5  
  2         144  
  2         11  
  2         10  
  1         9  
  1         4  
  1         6  
  2         139  
  2         12  
  2         11  
  4         588  
45             package $caller;
46             sub $atr :ATTR(CODE)
47             {
48             unshift \@_, q[$class], q[$caller];
49             my \$callback = "$class"->can("_callback");
50             goto \$callback;
51             }
52             };
53             namespace::clean->import(
54             -cleanee => $caller,
55             $opts->{attribute},
56 4         1368 );
57 4 100       300 unless ($FETCH{$caller})
58             {
59 1     1   271 no strict 'refs';
  1         2  
  1         473  
60 1         4 my $subname = "$caller\::FETCH_CODE_ATTRIBUTES";
61             *$subname = set_subname $subname => sub {
62 1     1   569 my ($class, $sub) = @_;
        1      
63 1 50       5 return map { /(\w+)$/ ? $1 : () }
  3         25  
64             __PACKAGE__->get_attributes($sub);
65 1         14 };
66 1         8 $FETCH{$caller} = 1;
67             }
68             }
69              
70             sub import
71             {
72 1     1   10 my $class = shift;
73 1         4 my $caller = caller;
74 1         3 foreach my $atr (@_)
75             {
76 4         21 $class->setup_for($caller, { attribute => $atr });
77             }
78             }
79              
80             sub _process_params
81             {
82 7     7   20 my ($class, $attr, $params) = @_;
83 7         19 return $params;
84             }
85              
86             sub _callback
87             {
88 7     7   30 my ($class, $installation_pkg, $caller_pkg, $glob, $ref, $attr, $params, $step, $file, $line) = @_;
89 7         30 my ($p, $n) = _identify($ref, scalar caller);
90 7         30 my $full_attr = join q[::], $installation_pkg, $attr;
91 7         28 my $obj = $class->_process_params($full_attr, $params);
92 7         48 $TALI{$p}{$n}{$full_attr} = $obj;
93             }
94              
95             sub get_attributes
96             {
97 4     4 1 1362 my ($class, $sub) = @_;
98 4         17 my ($p, $n) = _identify($sub, scalar caller);
99 4 50       8 my %hash = %{ $TALI{$p}{$n} || {} };
  4         27  
100 4         25 return sort keys %hash;
101             }
102              
103             sub get_attribute_parameters
104             {
105 3     3 1 560 my ($class, $sub, $attr) = @_;
106 3 50       13 $attr = scalar(caller).'::'.$attr unless $attr =~ /::/;
107 3         8 my ($p, $n) = _identify($sub, scalar caller);
108 3 50       10 return unless exists $TALI{$p}{$n}{$attr};
109 3         18 return $TALI{$p}{$n}{$attr};
110             }
111              
112             sub get_subs
113             {
114 3     3 1 1098 my ($class, $attr) = @_;
115 3 50       13 $attr = scalar(caller).'::'.$attr unless $attr =~ /::/;
116 3         5 my @subs;
117 3         18 foreach my $pkg (keys %TALI)
118             {
119             push @subs,
120 7         20 map { "$pkg\::$_" }
121 9         18 grep { exists $TALI{$pkg}{$_}{$attr} }
122 9         19 grep { not /^__ANON__\([0-9]+\)$/ }
123 3         6 keys %{ $TALI{$pkg} };
  3         8  
124             }
125 3         14 return @subs;
126             }
127              
128             1;
129              
130             __END__