如何使用“ use strict”导入常量,避免“不能使用bareword ...作为ARRAY引用”

时间:2019-03-07 14:41:11

标签: perl import module reference constants

我在文件中有一个模块,该模块导出一个常量,该常量是一个数组引用。我可以在其定义模块中使用该常量,但是在导入后不能使用它。错误消息显示为Can't use bareword ("AR") as an ARRAY ref while "strict refs" in use at mod.pl line 28.

考虑此演示代码:

#!/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.

我该如何解决?

3 个答案:

答案 0 :(得分:4)

在编译对常量的引用之前,需要执行import

您可以使用另一个BEGIN块来执行此操作,但这意味着我们现在有两个技巧。我建议不要采用以下方法,而不是弗兰肯斯坦对模块的用户和模块本身的看法。它使内联的程序包看起来尽可能多地成为一个真实的模块。

该方法包括以下内容:

  1. 在脚本开头的BEGIN块中按原样放置整个模块。
  2. 将结尾的1;替换为$INC{"Foo/Bar.pm"} = 1;(用于Foo::Bar)。

就是这样。这使您可以像平常一样use模块。

因此,如果您的模块如下:

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;

如果您的脚本如下:

#!/usr/bin/perl
use 5.018;
use warnings;

use Test qw( AR );

say AR->[1];

您可以使用以下内容:

#!/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];

如您所见,我进行了一些清理。具体来说,

  • 如果您需要5.18,则最好启用它提供的语言功能。这是通过将required 5.018;替换为use 5.018;来完成的
    • 我们不需要显式使用use strict;,因为use 5.012;和更高版本会启用严格限制。
    • 我们可以使用say,因为use 5.010;启用了它。
  • 测试不是导出器,因此它不应从导出器继承。在过去的15-20年中,Exporter提供的界面要比您使用的界面更好。
  • 如果不需要,无需创建或初始化@EXPORT
  • BEGIN@ISA的初始化周围不需要@EXPORT_OK块。

答案 1 :(得分:3)

print AR->[1]语句在编译时进行解析,但常量AR直到运行时才导入main命名空间中。

解决方法是确保在编译时将AR导入main

BEGIN { Test->import( qw(AR) ) }

还有运行时解决方法

print &AR->[1], "\n";
print AR()->[1], "\n";

答案 2 :(得分:1)

我改变了

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
}

# 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

您的代码现在可以使用

我怀疑在设置@EXPORT_OK变量之前,必须先在Exporter中运行一些代码