package Exporter::Lexical; use strict; use warnings; use 5.018; # ABSTRACT: exporter for lexical subs =head1 SYNOPSIS package My::Exporter; use Exporter::Lexical -exports => [ 'foo' ] sub foo { "FOO" } package MyApp; { use My::Exporter; warn foo(); # FOO } warn foo(); # Undefined subroutine &main::foo called =head1 DESCRIPTION This module allows you to export lexical subs from your exporter module. It is implemented using the new C feature in perl 5.18, so the functions truly are lexical (unlike some of the previous attempts). This module is quite experimental, and may change a lot in the future as I figure out how it should work. It is very much a proof of concept for the moment. =cut use XSLoader; XSLoader::load( __PACKAGE__, # we need to be careful not to touch $VERSION at compile time, otherwise # DynaLoader will assume it's set and check against it, which will cause # fail when being run in the checkout without dzil having set the actual # $VERSION exists $Exporter::Lexical::{VERSION} ? ${ $Exporter::Lexical::{VERSION} } : (), ); sub import { my $package = shift; my %opts = @_; my $caller = caller; my $import = build_exporter(\%opts, $caller); { no strict 'refs'; *{ $caller . '::import' } = $import; } } =func build_exporter(\%opts[, $caller]) my $import Exporter::Lexical::build_exporter({ -exports => ['foo'], }); This function just creates the method that it would install as your package's C method, without actually installing it. This lets you write your own import method that does whatever you want it to do, while still being able to export from it. =cut sub build_exporter { my ($opts, $caller) = @_; $caller //= caller; return sub { my $caller_stash = do { no strict 'refs'; \%{ $caller . '::' }; }; my @exports = @{ $opts->{'-exports'} }; my %exports = map { $_ => \&{ $caller_stash->{$_} } } @exports; for my $export (keys %exports) { lexical_import($export, $exports{$export}); } # XXX there is a bug with lexical_import where the pad entry sequence # numbers are incorrect when used with 'use', so the first statement # after the 'use' statement doesn't see the lexical. hack around this # for now by injecting a dummy statement right after the 'use'. _lex_stuff(";1;"); }; } =func lexical_import($name, $sub) Installs C<$sub> as a lexical subroutine into the currently compiling lexical scope. Throws an error if there is no currently compiling lexical scope (for instance, if this is called at runtime). =cut =head1 BUGS No known bugs. Please report any bugs through RT: email C, or browse to L. =head1 SEE ALSO L L L =head1 SUPPORT You can find this documentation for this module with the perldoc command. perldoc Exporter::Lexical You can also look for information at: =over 4 =item * MetaCPAN L =item * RT: CPAN's request tracker L =item * Github L =item * CPAN Ratings L =back =cut 1;