如何使用“使用严格”导入常量,避免“不能使用裸字......作为数组引用”

U. *_*ndl 4 import perl 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.
Run Code Online (Sandbox Code Playgroud)

我该如何解决?

ike*_*ami 5

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

你可以使用另一个BEGIN块来做到这一点,但这意味着我们现在有两个黑客。我建议采用以下方法,而不是对模块的用户和模块本身进行弗兰肯斯坦。它使内联包尽可能看起来像一个真正的模块。

该方法包括以下内容:

  1. 将整个模块按原样放置BEGIN在脚本开头的块中。
  2. 1;$INC{"Foo/Bar.pm"} = 1;(for 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;
Run Code Online (Sandbox Code Playgroud)

如果您的脚本如下:

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

use Test qw( AR );

say AR->[1];
Run Code Online (Sandbox Code Playgroud)

您可以使用以下内容:

#!/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];
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我做了一些清理工作。具体来说,

  • 如果您需要 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