How to import a constant with "use strict", avoiding "Can't use bareword ... as an ARRAY ref"

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?

How to Add a Constants File to Your React Project, in order to create an alias for your first constant when you import it. To each their own, but I actually prefer to import all of my constants in one go� Alert: Importing Excel file directly into Constant Contact might lead you to issues like permanent data loss, mismatched contact information or missing fields. Therefore, it is advised to not to import Excel file directly to Constant Contact and follow the steps below instead.

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

Java Constants – using Class, Interface, Static Imports, Constants are the constant things in a project. I mean, it is safe to assume that any project would have some kind of constant values used� import {EXISTINGACCOUNTURL as NEWACCOUNTURL} from './constants' … in order to create an alias for your first constant when you import it. To each their own, but I actually prefer to import all

I changed

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
}

to

# Inherit from Exporter to export functions and variables
use parent 'Exporter';
our $VERSION = 1.00;                # for version checking
our @EXPORT = qw();                 # exported by default
our @EXPORT_OK = qw(AR);            # can be optionally exported

and your code now works

I suspect that there is some code in Exporter that has to be run before you set up your @EXPORT_OK variable

Static Import, Static Import. In order to access static members, it is necessary to qualify references with the class they came from. For example, one must say: With Constant Contact, you can create effective email marketing and other online marketing campaigns to meet your business goals. Start your FREE trial today!

Python Variables, Constants and Literals, Then, we assign the constant value to PI and GRAVITY . After that, we create a main.py file and import the constant module. Finally, we print the constant value. In order to import custom field data, the custom fields must already exist in the Constant Contact account you are using. The example file uses custom fields named "first_name" and "vehicle_make_and_model_year".

Java Practices->Use static imports rarely, Concise presentations of java programming practices, tasks, and conventions, amply illustrated with syntax highlighted code examples. import math # Print the value of pi The math.pi constant returns the value pi: 3.141592653589793. It is defined as the ratio of the circumference to the diameter

Export and Import, Export and import directives have several syntax variants. 'Dec' ] ; // export a constant export const MODULES_BECAME_STANDARD_YEAR� TypeScript has multiple syntaxes for imports. When should you use which? It depends. 😞 Most of the time, the module exports multiple thingsThere are two great ways to import from another module when the module exports an object with properties. This is the common case. Import the whole module, giving it

Comments
  • @zdim: It's exactly the code presented in man perlmod(1).
  • ugh, you are right ... somebody should edit that, to not confuse people. It's a discussion with a point, no question, and that had been of practical relevance (20 years ago?), but that's not how we set up a module. See Exporter for a much simpler and clearer info (boilerplate) for that. And many SO posts of course, starting with ikegami's answer here
  • @zdim I've opened a perlbug with a patch: rt.perl.org/Ticket/Display.html?id=133909
  • @Grinnz Great, thank you. I looked over that part again, and it is indeed offered as a simple and practical overview of a module (so to speak). It should really be fixed.
  • So the real trick is $INC{"Test.pm"} = 1 and using a normal use Test? May I ask what does not work with my code? Also, it it possible to make "test.pm" independent of the actual file name being used?
  • No, I clearly listed two steps to "the trick", and that's only one of them. /// The name of the key in %INC in based on the package's name (i.e. based on the name the module world have), not the script's name.
  • @U.Windl The reason your code did not work as you expect is specifically because you are defining the module in the same file as you are using it, and at compile time (when you want to import the symbols to use for later) the module has thus not been run yet, and neither has your import call. If you keep modules in separate files, everything will work normally because the module will be compiled, run, and imported from in your script's compile phase by the use statement - your manual import on the other hand happens at runtime.
  • @Grinnz: I still have a problem with understanding: I thought that use constant ... is evaluated at compile time. I understand that the exporter stuff and the $INC{"Test.pm"} = 1 has to be inside a BEGIN block, but why all the rest?
  • It's just a lot shorter, simpler and cleaner to just wrap the whole module in a BEGIN block. It's also closer to the normal way of loading a module. Yes, you could use a normal block instead of a BEGIN block, and use multiple BEGIN blocks within (as shown here), but that's longer, and far more complicated, error-prone and messy. It also requires more indenting and more typing. There's simply no reason to do it that way.
  • That doesn't work in Perl 5.20 I get a Undefined subroutine &main::AR error message when using the AR() method you suggest
  • Odd, I'm on Perl 5.20.2 and it defiantly fails, which is why I added my answer. I guess someone fixed a bug between our two versions
  • All three solutions work fine in 5.20. In fact, they work fine in all versions from 5.6 to present (5.28) if you remove require 5.018_000;.
  • @ikegami: Want to comment on require 5.018_000? I thought it enables language feature up to Perl 5.18 (which is the version I had been using).
  • It just ensures the interpreter version is 5.18+. Totally unneeded for your program
  • This change doesn't help at all.