Perl Module using %EXPORT_TAGS

490 views Asked by At

I'm having trouble properly using %EXPORT_TAGS in my Perl module. In Solver.pl I have:

use MatrixFunctions qw(:Normal);

Then inside MatrixFunctions.pm, I have:

package MatrixFunctions;

use strict;
use Exporter;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);

$VERSION     = 1.00;
@ISA         = qw(Exporter);
@EXPORT      = ();
@EXPORT_OK   = qw(&det &identityMatrix &matrixAdd 
    &matrixScalarMultiply &matrixMultiplication);
%EXPORT_TAGS = ( Det => [qw(&det)],
    Normal => [qw(&det &identityMatrix &matrixAdd 
        &matrixScalarMultiply &matrixMultiplication)]);

However it only works when I have @EXPORT_OK including all the methods. If I have

@EXPORT_OK   = ();

I have the error:

"matrixScalarMultiply" is not exported by the MatrixFunctions module
 "det" is not exported by the MatrixFunctions module
 "matrixAdd" is not exported by the MatrixFunctions module
 "matrixMultiplication" is not exported by the MatrixFunctions module
 "identityMatrix" is not exported by the MatrixFunctions module
Can't continue after import errors at Solver.pl line 6.
BEGIN failed--compilation aborted at Solver.pl line 6.

The point of using qw(:Normal) in my Solver.pl file is so that I can have @EXPORT_OK empty I thought. What am I doing wrong?

2

There are 2 answers

0
Hunter McMillen On BEST ANSWER

perldoc -f Exporter under the Advanced Features section:

e.g., Module.pm defines:

@EXPORT = qw(A1 A2 A3 A4 A5);
@EXPORT_OK = qw(B1 B2 B3 B4 B5);
%EXPORT_TAGS = (T1 => [qw(A1 A2 B1 B2)], T2 => [qw(A1 A2 B3 B4)]);

Note that you cannot use tags in @EXPORT or @EXPORT_OK.

Names in EXPORT_TAGS must also appear in @EXPORT or @EXPORT_OK.

The bolded section above explains that you are required to have the functions you wish to place in %EXPORT_TAGS in either @EXPORT_OK or @EXPORT

A pattern that I have started using is to defined everything that I want to allow to be exported in @EXPORT_OK, then use @EXPORT_OK to build an `:all' tag:

our @ISA = qw(Exporter);
our @EXPORT_OK = qw/raspberry apple/;

our %EXPORT_TAGS = (
    'all' => \@EXPORT_OK,
);
0
ikegami On

[Not an answer, but a follow-up to large for a comment]

If you want @EXPORT_OK automatically populated, you can use the following:

push @EXPORTER_OK, map @$_, values %EXPORT_TAGS;

Exporter doesn't care about duplicate entries. If you do, you can use the following instead:

my %EXPORT_OK;
@EXPORT_OK = grep !$EXPORT_OK{$_}++,
    @EXPORT_OK, map @$_, values %EXPORT_TAGS;

So, after some cleaning up, your code would be the following:

package MatrixFunctions;

use strict;
use warnings;

use Exporter qw( import );

our $VERSION     = 1.00;
our @EXPORT      = ();
our @EXPORT_OK   = ();
our %EXPORT_TAGS = (
    Det    => [qw( det )],
    Normal => [qw( det identityMatrix matrixAdd matrixScalarMultiply matrixMultiplication )],
);

push @EXPORTER_OK, map @$_, values %EXPORT_TAGS;