File Coverage

lib/provide.pm
Criterion Covered Total %
statement 84 85 98.8
branch 12 18 66.6
condition 7 15 46.6
subroutine 23 23 100.0
pod 1 3 33.3
total 127 144 88.1


line stmt bran cond sub pod time code
1 1     1   50513 use strict;
  1         2  
  1         33  
2 1     1   5 use warnings;
  1         2  
  1         33  
3             package provide;
4              
5 1     1   6 use Exporter; # we shove it onto other people's @ISA, so we should load it ourselves
  1         6  
  1         143  
6              
7             our $VERSION = 0.03;
8              
9             sub import {
10 8     8   1312 my ($class, @args) = @_;
11              
12 8         27 my ($calling_class) = caller;
13              
14 8         20 my $match = pick_module_to_load(@args);
15 8 50       29 die "Couldn't parse @args, are you sure I know what I'm doing?" if !$match;
16 8         16 load($match);
17              
18             # set up the calling class as though it inherited from Exporter
19             {
20 1     1   5 no strict 'refs';
  1         2  
  1         80  
  8         10  
21 8         18 push @{"$calling_class\::ISA"}, qw(Exporter);
  8         78  
22 8         13 push @{"$calling_class\::EXPORT"}, @{"$match\::EXPORT"};
  8         34  
  8         1012  
23             }
24              
25             # export functions from $match to $calling_class so that users of $calling_class get them as
26             # though they were implemented in $calling_class, not in $match
27             {
28 1     1   5 no strict 'refs';
  1         1  
  1         3853  
  8         12  
29 8         11 for my $function (@{"$match\::EXPORT"}) {
  8         29  
30 9         12 *{"$calling_class\::$function"} = \&{"$match\::$function"};
  9         4804  
  9         24  
31             }
32             }
33             }
34              
35 21     21 0 107 sub looks_like_a_module { return shift() =~ m{^[\w:]+} }
36              
37             # try to load a module or die trying
38             sub load {
39 8     8 1 10 my ($module) = @_;
40              
41 8 50       15 if (looks_like_a_module($module)) {
42 8         17 local $@;
43 1     1   833 eval "use $module";
  1     1   884  
  1     1   55  
  1     1   2142  
  1     1   892  
  1     1   39  
  1     1   753  
  1     1   2  
  1         33  
  1         6  
  1         2  
  1         64  
  1         6  
  1         2  
  1         35  
  1         5  
  1         2  
  1         32  
  1         7  
  1         2  
  1         34  
  1         5  
  1         2  
  1         34  
  8         413  
44 8 50       385 die $@ if $@;
45             } else {
46 0         0 die "hit $module but it doesn't look like a module name, refusing to load it";
47             }
48             }
49              
50             sub pick_module_to_load {
51 8     8 0 24 my (@args) = @_;
52              
53 8         17 my @clauses = ([]);
54              
55 8         18 foreach (@args) {
56 60         56 push @{$clauses[-1]}, $_;
  60         103  
57 60 100 100     1034 push @clauses, [] if $clauses[-1][0] =~ /if|elsif/ && @{$clauses[-1]} == 4;
  44         160  
58             }
59              
60             my %condition = (
61 2     2   9 gt => sub { $] > shift() },
62 3     3   43 ge => sub { $] >= shift() },
63 2     2   15 eq => sub { $] == shift() },
64 2     2   13 ne => sub { $] != shift() },
65 1     1   13 le => sub { $] <= shift() },
66 1     1   15 lt => sub { $] < shift() },
67 8         135 );
68              
69 8         16 foreach (@clauses) {
70 13 100       32 if (@$_ == 4) {
    50          
71 11         22 my ($if, $condition, $version, $module) = @$_;
72              
73 11 50 33     128 die "can't handle line: @$_\n" unless
      33        
      33        
74             ($if =~ /if|elsif/) &&
75             exists $condition{$condition} &&
76             $version =~ /^\d[\.\d]*$/ &&
77             looks_like_a_module($module);
78              
79 11 100       885 return $module if $condition{$condition}->($version);
80             } elsif (@$_ == 2) {
81 2         4 my ($else, $module) = @$_;
82              
83 2 50 33     10 die "can't handle line: @$_\n" unless
84             $else eq 'else' &&
85             looks_like_a_module($module);
86              
87 2         23 return $module;
88             }
89             }
90             }
91              
92             1;
93              
94             __END__