File Coverage

blib/lib/Sub/Exporter/Lexical.pm
Criterion Covered Total %
statement 18 22 81.8
branch 3 8 37.5
condition n/a
subroutine 6 6 100.0
pod 1 1 100.0
total 28 37 75.6


line stmt bran cond sub pod time code
1 1     1   165333 use v5.12.0;
  1         5  
2 1     1   9 use warnings;
  1         4  
  1         149  
3             package Sub::Exporter::Lexical 1.001;
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 0   1   6 if ($] < 5.037002) { eval "require Lexical::Sub;" || die $@ }
  0 50       0  
13 1         778 else { require builtin; }
14             }
15              
16 1         9 use Sub::Exporter -setup => {
17             exports => [ qw(lexical_installer) ],
18 1     1   183 };
  1         4  
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   171 my ($arg, $to_export) = @_;
123              
124 1         3 my $into = $arg->{into};
125              
126 1         3 my @pairs = @$to_export;
127 1         6 while (my ($name, $code) = splice @pairs, 0, 2) {
128 1 50       3 if (ref $name) {
129             # We could implement this easily, but haven't. -- rjbs, 2013-11-24
130 0         0 Carp::cluck("can't import to variable with lexical installer (yet)");
131 0         0 next;
132             }
133              
134 1 50       4 if ($] >= 5.037002) { builtin::export_lexically($name, $code); }
  1         2077  
135 0         0 else { Lexical::Sub->import($name, $code); }
136             }
137 1     1 1 292 };
138             }
139              
140             1;
141              
142             __END__