| 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__ |