File Coverage

blib/lib/Evo/Export/Meta.pm
Criterion Covered Total %
statement 158 158 100.0
branch 44 72 61.1
condition 12 16 75.0
subroutine 21 21 100.0
pod 0 14 0.0
total 235 281 83.6


line stmt bran cond sub pod time code
1             package Evo::Export::Meta;
2 56     56   24875 use Evo 'Evo::Internal::Util; Carp croak; Module::Load load';
  56         136  
  56         417  
3              
4             our @CARP_NOT = qw(Evo Evo::Export Evo::Internal::Util);
5              
6 7067 50   7067 0 15984 sub package($self) { $self->{package} }
  7067 50       14951  
  7067         10667  
  7067         10122  
  7067         17936  
7 9521 50 100 9521 0 20991 sub symbols($self) { $self->{symbols} //= {} }
  9521 50       20087  
  9521         14243  
  9521         13467  
  9521         43991  
8              
9 332 50   332 0 4023 sub new ($me, $pkg, %opts) {
  332 50       1398  
  332         676  
  332         609  
  332         916  
  332         622  
10 332 50       958 $me = ref($me) if ref $me;
11 332         2512 bless {%opts, package => $pkg}, $me;
12             }
13              
14 3107 50   3107 0 8404 sub find_or_bind_to ($me, $pkg, %opts) {
  3107 50       7880  
  3107         5505  
  3107         4873  
  3107         7915  
  3107         5099  
15 56     56   16872 no strict 'refs'; ## no critic
  56         168  
  56         2803  
16 56     56   328 no warnings 'once';
  56         929  
  56         12466  
17 3107   66     4696 ${"${pkg}::EVO_EXPORT_META"} ||= $me->new($pkg, %opts);
  3107         19744  
18             }
19              
20             # it's important to return same function for the same module
21             # we're storing it in the module, not in slot, to be able to easy destroy a module
22 4198 50   4198 0 14091 sub request ($self, $name, $dpkg) {
  4198 50       9113  
  4198         6437  
  4198         6533  
  4198         6216  
  4198         5936  
23 4198         8352 my $slot = $self->find_slot($name);
24 4198         6717 my $fn;
25 4198         7483 my $type = $slot->{type};
26 4198 100       10538 if ($type eq 'code') {
    50          
27 2168         3683 $fn = $slot->{code};
28             }
29             elsif ($type eq 'gen') {
30 56     56   2223 no warnings 'once';
  56         129  
  56         1836  
31 56     56   304 no strict 'refs'; ## no critic
  56         116  
  56         31076  
32 2030         4308 my $pkg = $self->package;
33 2030   100     3261 my $cache = ${"${dpkg}::EVO_EXPORT_CACHE"} ||= {};
  2030         9676  
34 2030 100       5700 return $cache->{$pkg}{$name} if $cache->{$pkg}{$name};
35 2004         4309 return $cache->{$pkg}{$name} = $slot->{gen}->($self->package, $dpkg);
36             }
37              
38 2168 50       4733 croak "Something wrong" unless $fn;
39 2168         3994 return $fn;
40             }
41              
42             # traverse to find gen via links, return Module, name, gen
43 4730 50   4730 0 10597 sub find_slot ($self, $name) {
  4730 50       10022  
  4730         7514  
  4730         7108  
  4730         6616  
44 4730 100       9121 croak qq{"${\$self->package}" doesn't export "$name"} unless my $slot = $self->symbols->{$name};
  2         5  
45             }
46              
47 1998 50   1998 0 4926 sub init_slot ($self, $name, $val) {
  1998 50       4641  
  1998         3267  
  1998         3198  
  1998         3064  
  1998         2921  
48 1998         4284 my $pkg = $self->package;
49 1998 100       4669 croak "$pkg already exports $name" if $self->symbols->{$name};
50 1997         4491 $self->symbols->{$name} = $val;
51             }
52              
53 530 50   530 0 1484 sub export_from ($self, $name, $origpkg, $origname) {
  530 50       1384  
  530         943  
  530         898  
  530         861  
  530         869  
  530         875  
54 530         1102 my $slot = $self->find_or_bind_to($origpkg)->find_slot($origname);
55 529         1272 $self->init_slot($name, $slot);
56             }
57              
58 544 50   544 0 1546 sub export_gen ($self, $name, $gen) {
  544 50       1404  
  544         950  
  544         905  
  544         861  
  544         848  
59 544         2252 $self->init_slot($name, {gen => $gen, type => 'gen'});
60             }
61              
62 923 50   923 0 2798 sub export_code ($self, $name, $sub) {
  923 50       2268  
  923         1539  
  923         1522  
  923         1456  
  923         1428  
63 923         3647 $self->init_slot($name, {type => 'code', code => $sub});
64             }
65              
66 338 50   338 0 1045 sub export ($self, $name_as) {
  338 50       1368  
  338         828  
  338         821  
  338         537  
67 338         810 my $pkg = $self->package;
68 338         1381 my ($name, $as) = split ':', $name_as;
69 338   66     1928 $as ||= $name;
70 338         817 my $full = "${pkg}::$name";
71 56     56   496 no strict 'refs'; ## no critic
  56         862  
  56         37262  
72 338 100       660 my $sub = *{$full}{CODE} or croak "Subroutine $full doesn't exists";
  338         5347  
73 336         1536 $self->export_code($as, $sub);
74             }
75              
76              
77 100 50   100 0 423 sub export_proxy ($self, $origpkg, @xlist) {
  100         238  
  100         215  
  100         395  
  100         230  
78 100         328 $origpkg = Evo::Internal::Util::resolve_package($self->package, $origpkg);
79 100         595 load $origpkg;
80 100         7837 my @list = $self->find_or_bind_to($origpkg)->expand_wildcards(@xlist);
81              
82 100         347 foreach my $name_as (@list) {
83 528         1640 my ($origname, $name) = split ':', $name_as;
84 528   66     2475 $name ||= $origname;
85 528         1403 $self->export_from($name, $origpkg, $origname);
86             }
87             }
88              
89              
90 696 50   696 0 1932 sub expand_wildcards ($self, @list) {
  696         1268  
  696         2123  
  696         1287  
91 696         2293 my %symbols = $self->symbols->%*;
92 696         1841 my (%minus, %res);
93 696         1668 foreach my $cur (@list) {
94 959 100       2943 if ($cur eq '*') {
    100          
95 558 100       1583 croak "${\$self->package} exports nothing" unless %symbols;
  1         4  
96 557         3617 $res{$_}++ for keys %symbols;
97             }
98             elsif ($cur =~ /^-(.+)/) {
99 43         169 $minus{$1}++;
100             }
101             else {
102 358         1122 $res{$cur}++;
103             }
104             }
105 695         2171 return (sort grep { !$minus{$_} } keys %res);
  4751         14024  
106             }
107              
108 594 50   594 0 2148 sub install ($self, $dst, @xlist) {
  594         1212  
  594         1059  
  594         1883  
  594         1080  
109 594         1731 my @list = $self->expand_wildcards(@xlist);
110              
111 594         2444 my $liststr = join '; ', @list;
112 594         1657 my $exporter = $self->package;
113              
114 594         1211 my %patch;
115 594         1252 foreach my $name_as (@list) {
116 4179         12035 my ($name, $as) = split ':', $name_as;
117 4179   66     18524 $as ||= $name;
118 4179         8974 my $fn = $self->request($name, $dst);
119 4179         10408 $patch{$as} = $fn;
120             }
121 594         3147 Evo::Internal::Util::monkey_patch $dst, %patch;
122             }
123              
124 56     56   428 no warnings 'once';
  56         180  
  56         2829  
125             *info = *symbols;
126              
127             1;
128              
129             __END__