File Coverage

blib/lib/Exporter/LexicalVars.pm
Criterion Covered Total %
statement 62 67 92.5
branch 18 26 69.2
condition 8 13 61.5
subroutine 14 14 100.0
pod n/a
total 102 120 85.0


line stmt bran cond sub pod time code
1 2     2   47174 use 5.008003;
  2         7  
  2         73  
2 2     2   11 use strict;
  2         2  
  2         74  
3 2     2   17 use warnings;
  2         12  
  2         75  
4              
5             package Exporter::LexicalVars;
6              
7 2     2   11 use B qw();
  2         10  
  2         35  
8 2     2   1696 use B::Hooks::Parser qw();
  2         7065  
  2         51  
9 2     2   16 use Carp qw(croak);
  2         4  
  2         157  
10 2     2   1737 use Exporter::Shiny qw(import);
  2         7371  
  2         13  
11              
12             BEGIN {
13             eval {
14 2         2625 require List::MoreUtils;
15 0         0 'List::MoreUtils'->import('uniq');
16 0         0 1;
17             }
18             or *uniq = sub {
19 4     4   7 my %already;
20 4         30 grep !$already{$_}++, @_;
21 2 50   2   233 };
22             };
23              
24             our $AUTHORITY = 'cpan:TOBYINK';
25             our $VERSION = '0.001';
26             our %EXPORT_TAGS = ( setup => [qw(import)] );
27             our @INIT;
28              
29             sub _generate_import
30             {
31 2     2   374 my $me = shift;
32 2         6 my ($name, $args, $globals) = @_;
33 2         3 my $caller = $globals->{into};
34            
35 2         7 (my $nominal_file = $caller) =~ s(::)(/)g;
36 2   50     21 $INC{"$nominal_file\.pm"} ||= __FILE__;
37            
38 2         2 my (%inject, @vars, @tags);
39 2         15 for (sort keys %$args)
40             {
41 9 50       48 /\A[\$\@\%][^\W0-9]\w*\z/ ? push(@vars, $_) :
    100          
42             /\A[:-](\w*)\z/ ? push(@tags, ":$1") :
43             croak("Not a legal name for a lexical variable or tag: '$_'");
44             }
45            
46 2         9 $inject{$_} = $me->_setup_lexical_variable($args, $_) for @vars;
47 2         16 $inject{$_} = $me->_setup_tag($args, $_) for @tags;
48 2   50     18 $inject{":all"} ||= [sort @vars];
49            
50 2     4   16 return sub { $me->_handle_inject(\%inject, @_) };
  4         26667  
51             }
52              
53             sub _handle_inject
54             {
55 4     4   9 my $me = shift;
56 4         15 my $inject = shift;
57 4         6 my $package = shift;
58            
59             # Handle tag expansion
60 4 50 33     17 @_ = @{ $inject->{':default'} or $inject->{':all'} or [] } unless @_;
  1 100       14  
61 2 50       20 @_ = uniq map {
62 4         9 /\A[:-](\w*)\z/
63 9 100       47 ? @{ $inject->{":$1"} or croak("Tag $1 not exported by $package") }
64             : $_
65             } @_;
66            
67 12 50       42 my @code = map {
68 4         10 $inject->{$_} or croak("Variable $_ not exported by $package")
69             } @_;
70 4         30 B::Hooks::Parser::inject(join(';', '', @code));
71             }
72              
73             sub _setup_lexical_variable
74             {
75 8     8   12 my $me = shift;
76 8         12 my ($args, $var) = @_;
77 8         21 my $value = $args->{$var};
78            
79 8 50 100     53 if ($var =~ /\A[\@\%]/ and defined($value) and not ref($value))
      66        
80             {
81 0         0 croak("Cannot initialize $var from a scalar value");
82             }
83            
84 8 100       20 if (!ref($value))
85             {
86 4 100       52 return sprintf(
87             'my(%s)=(%s);',
88             $var,
89             defined($value) ? B::perlstring($value) : '',
90             );
91             }
92            
93 4 50       14 if (ref($value) eq q(CODE))
94             {
95 4         7 push @INIT, $value;
96 4         55 return sprintf(
97             'my(%s);$%s::INIT[%d]->(\\%s, %s);',
98             $var,
99             __PACKAGE__,
100             $#INIT,
101             $var,
102             B::perlstring($var),
103             );
104             }
105            
106 0         0 croak("Cannot setup variable $var from reference of type " . ref($value));
107             }
108              
109             sub _setup_tag
110             {
111 1     1   1 my $me = shift;
112 1         3 my ($args, $var) = @_;
113 1         2 my $value = $args->{$var};
114            
115 1 50       7 return $value if ref($value) eq q(ARRAY);
116            
117 0           croak("Cannot setup tag $var from reference of type " . ref($value));
118             }
119              
120             1;
121              
122             __END__