k.lo
k.lo

Reputation: 423

Multiple package with Exporter

I'm trying to get familiar with Perl Exporter. The issue I am facing is whatever I try, I cannot use Exporter with modules containing multiple packages in it. What am I missing below?

MyModule.pm

use strict;
use warnings;

package Multipackage1;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(test1);

sub test1 {

  print "First package\n";
  
}

1;

package Multipackage2;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(test2);

sub test2 {

   print "Second package\n";
   
}

1;

package Multipackage3;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw(test3);

sub test3 {

   print "Third package\n";
   
}

1;

MyMainFile.pl

#!/usr/bin/perl 

use strict;
use warnings;
use Multipackage;
use Multipackage qw(test3);

print "Calling first package:\n";
test1();
print "Calling second package:\n";
test2();
print "Calling third package:\n";
test3();

I'm getting test1 is not part of the main package.

Upvotes: 9

Views: 260

Answers (1)

zdim
zdim

Reputation: 66883

The use calls require, which looks for a file with the package name (with / for :: and + .pm).

So require the actual file with packages instead and then import from packages.

main.pl

use warnings;
use strict;

require MyModule;

import Multipackage1;
import Multipackage2;
import Multipackage3 qw(test3);

print "Calling first package:\n";
test1();
print "Calling second package:\n";
test2();
print "Calling third package:\n";
test3();

In MyModule.pm, place each package in its own block to provide scope for lexical variables since package doesn't do that, or use package Pack { ... } since v5.14. There is no need for all those 1s, and you may pull use Exporter; out of the blocks.

Output

Calling first package:
First package
Calling second package:
Second package
Calling third package:
Third package

Better yet, replace our @ISA = qw(Exporter); with use Exporter qw(import); for

use strict;
use warnings;

package Multipackage1 {
    use Exporter qw(import);
    our @EXPORT = qw(test1);

    sub test1 { print "First package\n" }
}
...
1;

with the same output. See Exporter.

Note that putting multiple packages in one file is normally not needed and not done.

Upvotes: 12

Related Questions