in reply to Using Modules

And for the sake of thoroughness there are a few cases inside My::Module::Another that do the following: My::Module::asub1();

So in package My::Module::Another, do you do use My::Module? Because if not, that's not quite correct - you're relying on My::Module being loaded by someone else, which might not always be true.

Also, it sounds to me like you might have a circular dependency brewing. Two relatively easy ways to solve that would be to either move the commonly used functions into a third module, or in your case (no OO, and interdependencies between the modules) consider maybe merging the two modules into a single one - unless of course this would cause you to end up with one giant messy file.

Another important question is whether you can guarantee that the names of the functions exported from the two modules will never collide? If you can, then one simple way to export everything at once would be to import the functions from My::Module::Another into My::Module, and then re-export them from there:

package My::Module; use Exporter 'import'; use My::Module::Another; our @EXPORT = ( qw/asub1 asub2 asub3/, @My::Module::Another::EXPORT );

There are other, trickier ways to accomplish the same thing without exporting everything from My::Module::Another into My::Module or vice versa, by writing your own import function. However, this is certainly a more advanced technique, and I would strongly recommend thinking about the above solutions (including whether to merge your modules into one) before going this far. Also, note that I've had to remove support for explicit export lists in this example, since a "merged" list would cause one module to complain since it doesn't know about the other's functions, so this solution isn't without its disadvantages.

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]); }

Lastly, it's also possible to write your own import function and not use Exporter, although this is one of those cases of "do this only if you know what you are doing and why". Also, you lose the functionality of Exporter, such as tags etc. I'm just showing this as a proof-of-concept for completeness, which is why I haven't added support for export lists (Update: added that functionality, note that this assumes there are no duplicate sub names in the modules). I re-use the @EXPORT variable that Exporter uses, but note there is no requirement for this as the variable isn't special - I could also just hard-code the list of functions or use a different variable if I like.

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"}; } } }

This is probably a case of "just enough rope to shoot yourself in the foot", but I think it's important to know that what use and Exporter are doing isn't magic, and it is possible to DIY.

Update 2: Minor tweaks to wording.