I have a module in a file that exports a constant that is an array reference. I can use that constant inside its defining module, but I cannot use it after importing it. The error message says Can't use bareword ("AR") as an ARRAY ref while "strict refs" in use at mod.pl line 28.
.
Consider this demo code:
#!/usr/bin/perl
require 5.018_000;
use warnings;
use strict;
package Test;
use warnings;
use strict;
BEGIN {
require Exporter;
our $VERSION = 1.00; # for version checking
# Inherit from Exporter to export functions and variables
our @ISA = qw(Exporter);
our @EXPORT = qw(); # exported by default
our @EXPORT_OK = qw(AR); # can be optionally exported
}
use constant AR => [1,2,3];
print AR->[1], "\n";
1;
package main;
Test->import(qw(AR));
print AR->[1], "\n";
#Can't use bareword ("AR") as an ARRAY ref while "strict refs" in use at mod.pl line 28.
How can I fix it?
You need to execute the import
before a reference to the constant is compiled.
You could use yet another BEGIN
block to do that, but that means we have now two hacks. Rather than frankensteining both the module's user and the module itself, I suggest the following approach. It keeps the inlined package looking as much as a real module as possible.
The approach consists of the following:
BEGIN
block at the start of the script.1;
with $INC{"Foo/Bar.pm"} = 1;
(for Foo::Bar
).That's it. This allows you to use
the module as normal.
So if your module is the following:
package Test;
use strict;
use warnings;
use Exporter qw( import );
our $VERSION = 1.00;
our @EXPORT_OK = qw(AR);
use constant AR => [1,2,3];
1;
And if your script is the following:
#!/usr/bin/perl
use 5.018;
use warnings;
use Test qw( AR );
say AR->[1];
You can use the following:
#!/usr/bin/perl
BEGIN {
package Test;
use strict;
use warnings;
use Exporter qw( import );
our $VERSION = 1.00;
our @EXPORT_OK = qw(AR);
use constant AR => [1,2,3];
$INC{__PACKAGE__ .'.pm'} = 1; # Tell Perl the module is already loaded.
}
use 5.018;
use warnings;
use Test qw( AR );
say AR->[1];
As you can see, I've made some cleanups. Specifically,
required 5.018;
with use 5.018;
use strict;
explicitly because use 5.012;
and higher enable strictures.say
because use 5.010;
enables it.@EXPORT
if you don't need it.BEGIN
block around the initialization of @ISA
and @EXPORT_OK
.The print AR->[1]
statement is parsed during compile time but the constant AR
isn't imported into the main
namespace until runtime.
The fix is to make sure that AR
gets imported into main
at compile-time
BEGIN { Test->import( qw(AR) ) }
There are also run-time workarounds
print &AR->[1], "\n";
print AR()->[1], "\n";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With