File Coverage

blib/lib/Sub/Exporter/Lexical.pm
Criterion Covered Total %
statement 21 25 84.0
branch 4 8 50.0
condition 2 3 66.6
subroutine 6 6 100.0
pod 1 1 100.0
total 34 43 79.0


line stmt bran cond sub pod time code
1 1     1   84908 use v5.12.0;
  1         9  
2 1     1   5 use warnings;
  1         2  
  1         68  
3             package Sub::Exporter::Lexical 1.000;
4             # ABSTRACT: to export lexically-available subs with Sub::Exporter
5              
6             # I know about if.pm! But we can't use it here because "use Lexical::Sub" will
7             # call import and then it dies "does no default importation". And then what
8             # about this *utterly ridiculous* require? Well, that's to avoid the prereq
9             # scanner picking up Lexical::Sub, which I do not want to just RemovePrereqs
10             # on, because that runs after the thing that adds optional prereqs.
11             BEGIN {
12 1 50   1   5 if ($] < 5.037002) { eval "require Lexical::Sub;" || die $@ }
  1 50       62  
13 0         0 else { require builtin; }
14             }
15              
16 1         7 use Sub::Exporter -setup => {
17             exports => [ qw(lexical_installer) ],
18 1     1   3376 };
  1         3  
19              
20             #pod =head1 SYNOPSIS
21             #pod
22             #pod In an exporting library:
23             #pod
24             #pod package Some::Toolkit;
25             #pod
26             #pod use Sub::Exporter -setup => {
27             #pod exports => [ qw(foo bar baz) ],
28             #pod };
29             #pod
30             #pod sub foo { ... }
31             #pod sub bar { ... }
32             #pod sub baz { ... }
33             #pod
34             #pod In an importing library:
35             #pod
36             #pod package Vehicle::Autobot;
37             #pod
38             #pod use Sub::Exporter::Lexical lexical_installer => { -as => 'lex' };
39             #pod
40             #pod ...;
41             #pod
42             #pod {
43             #pod use Some:::Toolkit { installer => lex }, qw(foo bar);
44             #pod
45             #pod foo(1,2,3);
46             #pod my $x = bar;
47             #pod
48             #pod ...
49             #pod };
50             #pod
51             #pod # ... and here, foo and bar are no longer available ...
52             #pod
53             #pod =head1 DESCRIPTION
54             #pod
55             #pod Sub::Exporter::Lexical provides an alternate installer for
56             #pod L. Installers are documented in Sub::Exporter's
57             #pod documentation; all you need to know is that by using Sub::Exporter::Lexical's
58             #pod installer, you can import routines into a lexical scope that will be cleaned up
59             #pod when that scope ends.
60             #pod
61             #pod There are two places it makes sense to use the lexical installer: when
62             #pod configuring Sub::Exporter in your exporting package or when importing from a
63             #pod package that uses Sub::Exporter. For the first case, do something like this:
64             #pod
65             #pod package Some::Toolkit;
66             #pod use Sub::Exporter::Lexical ();
67             #pod use Sub::Exporter -setup => {
68             #pod exports => [ ... ],
69             #pod installer => Sub::Exporter::Lexical::lexical_installer,
70             #pod };
71             #pod
72             #pod For the second:
73             #pod
74             #pod package My::Library;
75             #pod
76             #pod use Sub::Exporter::Lexical ();
77             #pod use Some::Toolkit
78             #pod { installer => Sub::Exporter::Lexical::lexical_installer },
79             #pod qw(foo bar baz);
80             #pod
81             #pod =head1 EXPORTS
82             #pod
83             #pod Sub::Exporter::Lexical offers only one routine for export, and it may also
84             #pod be called by its full package name:
85             #pod
86             #pod =head2 lexical_installer
87             #pod
88             #pod This routine returns an installer suitable for use as the C argument
89             #pod to Sub::Exporter. It installs all requested routines as usual, but marks them
90             #pod to be removed from the target package as soon as the block in which it was
91             #pod called is complete.
92             #pod
93             #pod It does not affect the behavior of routines exported into scalar references.
94             #pod
95             #pod B, it does not affect scopes in which it is invoked at
96             #pod runtime, rather than compile time. B It means that this
97             #pod works:
98             #pod
99             #pod {
100             #pod use Some::Toolkit { installer => lexical_installer }, qw(foo);
101             #pod foo(1,2,3);
102             #pod }
103             #pod
104             #pod foo(); # this dies
105             #pod
106             #pod ...but this does not...
107             #pod
108             #pod {
109             #pod require Some::Toolkit;
110             #pod Some::Toolkit->import({ installer => lexical_installer }, qw(foo));
111             #pod foo(1,2,3);
112             #pod }
113             #pod
114             #pod foo(); # this does not die, even though you might expect it to
115             #pod
116             #pod Finally, you can't supply a C<< -as => \$var >> install destination yet.
117             #pod
118             #pod =cut
119              
120             sub lexical_installer {
121             sub {
122 1     1   130 my ($arg, $to_export) = @_;
123              
124 1         2 my $into = $arg->{into};
125              
126             my @names =
127 1         3 map { $to_export->[ $_ ] }
128 1   66     3 grep { not($_ % 2) and ! ref $to_export->[$_] } (0 .. $#$to_export);
  2         15  
129              
130 1         3 my @pairs = @$to_export;
131 1         4 while (my ($name, $code) = splice @pairs, 0, 2) {
132 1 50       3 if (ref $name) {
133             # We could implement this easily, but haven't. -- rjbs, 2013-11-24
134 0         0 Carp::cluck("can't import to variable with lexical installer (yet)");
135 0         0 next;
136             }
137              
138 1 50       3 if ($] >= 5.037002) { builtin::export_lexically($name, $code); }
  0         0  
139 1         1307 else { Lexical::Sub->import($name, $code); }
140             }
141 1     1 1 217 };
142             }
143              
144             1;
145              
146             __END__