我自己的 Test::Version 的提要就是一个例子来说明。

use Test::More;
use Test::Version 0.04;

# test blib or lib by default
version_all_ok();

done_testing;

我不必在done_testing();上加上括号,我可以简单地称呼它。但是,当我尝试调用version_all_ok;时(注意:Dist::Zilla::Plugin::Test::Version的首次尝试以这种方式失败了),我得到了一个错误。为什么是这样?

更新也许我的示例并不像我想象的那样好。我得到的实际错误是
Bareword "version_all_ok" not allowed while "strict subs" in use at t/release-test-version.t line 19.

这是完整的代码
#!/usr/bin/perl

BEGIN {
  unless ($ENV{RELEASE_TESTING}) {
    require Test::More;
    Test::More::plan(skip_all => 'these tests are for release candidate testing');
  }
}

use 5.006;
use strict;
use warnings;
use Test::More;

eval "use Test::Version";
plan skip_all => "Test::Version required for testing versions"
    if $@;

version_all_ok; # of course line 19, and version_all_ok() works here.
done_testing;

以下应该是从Test::Version 1.0.0中提取的相关片段,以进行导出。
use parent 'Exporter';
our @EXPORT = qw( version_all_ok ); ## no critic (Modules::ProhibitAutomaticExportation)
our @EXPORT_OK = qw( version_ok );

最佳答案

从根本上讲,因为Perl需要知道一个裸字意味着一个函数调用才能将其解析为一个函数调用。 Perl可以通过两种方式了解这个有趣的事实:

  • 您可能已经将裸词修饰为函数调用,在&->之前添加,或在(...)后面添加这两者。 Perl将相信您知道您在说什么,并将裸字解析为函数调用,即使它尚不知道必须调用什么函数也是如此。
  • 在Perl尝试解析该调用之前,您可能已经使用该名称声明了一个函数。通常,给模块添加use就足以确保在正确的时间创建符号。您在Test::Version中做错了什么,因此直到需要编译测试脚本之后,才导出该符号。

  • 在您的代码中,您将use包装在eval中,这实际上将其延迟到执行时间。因此,当Perl尝试编译该调用并将其炸毁时,符号version_all_ok不可用。强制eval编译时间应足以使符号可用:
    BEGIN {
        eval "use Test::Version";
        plan skip_all => "Test::Version required for testing versions"
            if $@;
    }
    

    09-10 11:03
    查看更多