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

问题描述 投票:4回答:3

我在文件中有一个模块,它导出一个作为数组引用的常量。我可以在其定义模块中使用该常量,但导入后我无法使用它。错误消息说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.

我该如何解决?

perl import module reference constants
3个回答
4
投票

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

你可以使用另一个BEGIN块来做到这一点,但这意味着我们现在有两个黑客。我建议使用以下方法,而不是对模块的用户和模块本身进行frankensteining。它使内联包保持尽可能多的真实模块。

该方法包括以下内容:

  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;能够实现它。
  • 测试不是导出器,因此不应从Exporter继承。在过去的15到20年间,Exporter一直提供比您使用的界面更好的界面。
  • 如果您不需要,则无需创建或初始化@EXPORT
  • BEGIN@ISA的初始化周围不需要@EXPORT_OK块。

3
投票

print AR->[1]语句在编译期间被解析,但是常量AR在运行时之前不会导入main命名空间。

修复是为了确保AR在编译时导入main

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

还有运行时解决方法

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

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中运行一些代码

© www.soinside.com 2019 - 2024. All rights reserved.