package My::Module;
use Exporter 'import';
use My::Module::Another;
our @EXPORT = ( qw/asub1 asub2 asub3/, @My::Module::Another::EXPORT );
####
package My::Module::Another;
use base 'Exporter';
our @EXPORT = qw/bsub1 bsub2 bsub3/;
####
package My::Module;
use base 'Exporter';
our @EXPORT = qw/asub1 asub2 asub3/;
use My::Module::Another;
sub import {
warn "WARNING: Ignoring export list!" if @_>1;
__PACKAGE__->export_to_level(1, $_[0]);
My::Module::Another->export_to_level(1, $_[0]);
}
####
package My::Module;
# no "use Exporter" or "use base 'Exporter'", we're on our own!
# ...
use Carp;
our @EXPORT_FROM_PACKS = qw/ My::Module My::Module::Another /;
sub import {
my ($class, @export) = @_;
my ($callerpack) = caller;
my %export = map {$_=>1} @export;
for my $frompack (@EXPORT_FROM_PACKS) { # loop over packages
# attempt to load that module
eval "require $frompack; 1"
or croak "failed to load $frompack: $@";
# get their @EXPORT variable
my @exps = do { no strict 'refs'; @{"${frompack}::EXPORT"} };
for my $ex (@exps) { # loop over their exports
next if @export && !$export{$ex};
no strict 'refs'; # limit scope of "no strict"
# target function <-- source function
*{"${callerpack}::$ex"} = \&{"${frompack}::$ex"};
}
}
}