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   22857 use Evo 'Evo::Internal::Util; Carp croak; Module::Load load';
  56         125  
  56         417  
3              
4             our @CARP_NOT = qw(Evo Evo::Export Evo::Internal::Util);
5              
6 6539 50   6539 0 13345 sub package($self) { $self->{package} }
  6539 50       12695  
  6539         8936  
  6539         8466  
  6539         14158  
7 8927 50 100 8927 0 17961 sub symbols($self) { $self->{symbols} //= {} }
  8927 50       17312  
  8927         12158  
  8927         11648  
  8927         34619  
8              
9 299 50   299 0 4504 sub new ($me, $pkg, %opts) {
  299 50       717  
  299         499  
  299         479  
  299         680  
  299         443  
10 299 50       738 $me = ref($me) if ref $me;
11 299         1998 bless {%opts, package => $pkg}, $me;
12             }
13              
14 2887 50   2887 0 7205 sub find_or_bind_to ($me, $pkg, %opts) {
  2887 50       6685  
  2887         4393  
  2887         4218  
  2887         6664  
  2887         4287  
15 56     56   15796 no strict 'refs'; ## no critic
  56         142  
  56         1695  
16 56     56   303 no warnings 'once';
  56         129  
  56         9715  
17 2887   66     3988 ${"${pkg}::EVO_EXPORT_META"} ||= $me->new($pkg, %opts);
  2887         15490  
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 3912 50   3912 0 13352 sub request ($self, $name, $dpkg) {
  3912 50       7852  
  3912         5501  
  3912         5640  
  3912         5521  
  3912         5104  
23 3912         6711 my $slot = $self->find_slot($name);
24 3912         5791 my $fn;
25 3912         6172 my $type = $slot->{type};
26 3912 100       8721 if ($type eq 'code') {
    50          
27 2047         3113 $fn = $slot->{code};
28             }
29             elsif ($type eq 'gen') {
30 56     56   1005 no warnings 'once';
  56         117  
  56         1609  
31 56     56   276 no strict 'refs'; ## no critic
  56         107  
  56         32651  
32 1865         3356 my $pkg = $self->package;
33 1865   100     2808 my $cache = ${"${dpkg}::EVO_EXPORT_CACHE"} ||= {};
  1865         7289  
34 1865 100       4644 return $cache->{$pkg}{$name} if $cache->{$pkg}{$name};
35 1839         3385 return $cache->{$pkg}{$name} = $slot->{gen}->($self->package, $dpkg);
36             }
37              
38 2047 50       4140 croak "Something wrong" unless $fn;
39 2047         3437 return $fn;
40             }
41              
42             # traverse to find gen via links, return Module, name, gen
43 4411 50   4411 0 8830 sub find_slot ($self, $name) {
  4411 50       8531  
  4411         6101  
  4411         6186  
  4411         5721  
44 4411 100       7583 croak qq{"${\$self->package}" doesn't export "$name"} unless my $slot = $self->symbols->{$name};
  2         5  
45             }
46              
47 1899 50   1899 0 4299 sub init_slot ($self, $name, $val) {
  1899 50       4033  
  1899         2712  
  1899         2682  
  1899         2700  
  1899         2543  
48 1899         3656 my $pkg = $self->package;
49 1899 100       3924 croak "$pkg already exports $name" if $self->symbols->{$name};
50 1898         3795 $self->symbols->{$name} = $val;
51             }
52              
53 497 50   497 0 1129 sub export_from ($self, $name, $origpkg, $origname) {
  497 50       1167  
  497         890  
  497         733  
  497         725  
  497         710  
  497         683  
54 497         919 my $slot = $self->find_or_bind_to($origpkg)->find_slot($origname);
55 496         1053 $self->init_slot($name, $slot);
56             }
57              
58 544 50   544 0 1390 sub export_gen ($self, $name, $gen) {
  544 50       1236  
  544         865  
  544         786  
  544         789  
  544         765  
59 544         1936 $self->init_slot($name, {gen => $gen, type => 'gen'});
60             }
61              
62 857 50   857 0 2535 sub export_code ($self, $name, $sub) {
  857 50       1861  
  857         1428  
  857         1259  
  857         1221  
  857         1198  
63 857         2945 $self->init_slot($name, {type => 'code', code => $sub});
64             }
65              
66 316 50   316 0 866 sub export ($self, $name_as) {
  316 50       1099  
  316         559  
  316         585  
  316         455  
67 316         660 my $pkg = $self->package;
68 316         1073 my ($name, $as) = split ':', $name_as;
69 316   66     1536 $as ||= $name;
70 316         672 my $full = "${pkg}::$name";
71 56     56   394 no strict 'refs'; ## no critic
  56         720  
  56         33911  
72 316 100       487 my $sub = *{$full}{CODE} or croak "Subroutine $full doesn't exists";
  316         4396  
73 314         936 $self->export_code($as, $sub);
74             }
75              
76              
77 89 50   89 0 324 sub export_proxy ($self, $origpkg, @xlist) {
  89         178  
  89         160  
  89         285  
  89         164  
78 89         250 $origpkg = Evo::Internal::Util::resolve_package($self->package, $origpkg);
79 89         404 load $origpkg;
80 89         5891 my @list = $self->find_or_bind_to($origpkg)->expand_wildcards(@xlist);
81              
82 89         261 foreach my $name_as (@list) {
83 495         1406 my ($origname, $name) = split ':', $name_as;
84 495   66     2091 $name ||= $origname;
85 495         1024 $self->export_from($name, $origpkg, $origname);
86             }
87             }
88              
89              
90 619 50   619 0 1484 sub expand_wildcards ($self, @list) {
  619         990  
  619         1418  
  619         955  
91 619         1362 my %symbols = $self->symbols->%*;
92 619         1455 my (%minus, %res);
93 619         1274 foreach my $cur (@list) {
94 860 100       2237 if ($cur eq '*') {
    100          
95 503 100       1217 croak "${\$self->package} exports nothing" unless %symbols;
  1         3  
96 502         2952 $res{$_}++ for keys %symbols;
97             }
98             elsif ($cur =~ /^-(.+)/) {
99 21         68 $minus{$1}++;
100             }
101             else {
102 336         643 $res{$cur}++;
103             }
104             }
105 618         1657 return (sort grep { !$minus{$_} } keys %res);
  4410         11667  
106             }
107              
108 528 50   528 0 1430 sub install ($self, $dst, @xlist) {
  528         862  
  528         824  
  528         1352  
  528         844  
109 528         1296 my @list = $self->expand_wildcards(@xlist);
110              
111 528         1928 my $liststr = join '; ', @list;
112 528         1300 my $exporter = $self->package;
113              
114 528         901 my %patch;
115 528         1113 foreach my $name_as (@list) {
116 3893         9512 my ($name, $as) = split ':', $name_as;
117 3893   66     15485 $as ||= $name;
118 3893         7434 my $fn = $self->request($name, $dst);
119 3893         8649 $patch{$as} = $fn;
120             }
121 528         2326 Evo::Internal::Util::monkey_patch $dst, %patch;
122             }
123              
124 56     56   400 no warnings 'once';
  56         116  
  56         2491  
125             *info = *symbols;
126              
127             1;
128              
129             __END__