I have looked for the last few hours and I am stumped.
I did see How can I share variables between a base class and subclass in Perl? but it does not answer my question
I am trying to write a utility module (testing purposes at this point) for use in internally developed scripts. But I seem to be having a tough go at getting exporter to actually export what I need it to.
What I have is below:
lib/Internal.pm:
package Internal;
use 5.008_008;
use strict;
use warnings;
use Exporter;
our $VERSION = 1;
our @EXPORT_OK = qw($EMPTY $NOW);
our %EXPORT_TAGS = ( ':all' => \@EXPORT_OK );
our $EMPTY = q{};
our $NOW = time;
1;
lib/Internal/Utility.pm:
package Internal::Utility;
use 5.008_008;
use strict;
use warnings;
use FindBin::libs;
use parent qw(Internal);
use Data::Dumper;
our $VERSION = 1;
our @EXPORT_OK = qw(run);
our %EXPORT_TAGS = ( ':all' => \@EXPORT_OK );
sub run
{
print Dumper $NOW;
print Dumper $EMPTY;
exit;
}
1;
bin/test.pl:
#!/usr/bin/env perl
use 5.008_008;
use strict;
use warnings;
use FindBin::libs;
use Internal::Utility qw(:all);
run();
exit;
When I run the test.pl, I get the below error:
Global symbol "$NOW" requires explicit package name at lib/Internal/Utility.pm line 8.
Global symbol "$EMPTY" requires explicit package name at lib/Internal/Utility.pm line 9.
Compilation failed in require at ./test.pl line 7.
BEGIN failed--compilation aborted at ./test.pl line 7.
Why is the use parent
in Internal::Utility not importing the variables from Internal.pm? Is there a way to tell use parent to explicitly import some variable?
In Perl, inheritance only affects how method calls are resolved. Everything else – variables, subroutines, and so on – remains just the same.
That means you should import those symbols into your derived class, just like you'd import from any other module:
package Internal::Utility;
...
use Internal ':all';
use parent qw(Internal);
...
Perl uses packages as its sole namespacing mechanisms, but packages can also be used as classes. This can be a bit confusing. As a general advice, you should never mix those two: a package should EITHER offer an object-oriented interface OR an exporter-based, procedural interface. Mixing the two tends to result in misleading designs.