为什么Perl中的某些函数必须用parens调用而其他函数不调用?

xen*_*ide 10 perl

举例说明的是我自己的概要Test::Version.

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

# test blib or lib by default
version_all_ok();

done_testing;
Run Code Online (Sandbox Code Playgroud)

我不必包括括号,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.
Run Code Online (Sandbox Code Playgroud)

这是完整的代码

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

以下内容应该是从Test::Version 1.0.0出口中提取的相关摘录.

use parent 'Exporter';
our @EXPORT = qw( version_all_ok ); ## no critic (Modules::ProhibitAutomaticExportation)
our @EXPORT_OK = qw( version_ok );
Run Code Online (Sandbox Code Playgroud)

dar*_*rch 15

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

  1. 你可能已经布置得像一个函数调用的裸词的前面加上&->或追加(...)或两者兼而有之.Perl会相信你知道你在说什么,并将裸字解析为函数调用,即使它还不知道它将调用什么函数.

  2. 在Perl尝试解析调用之前,您可能已声明具有该名称的函数.通常,use-ing模块足以确保在正确的时间创建符号; 你做错了什么Test::Version,直到需要编译测试脚本之后才导出符号.

在你的代码中,你将use内部包装起来eval,这有效地将它延迟到执行时间.因此,version_all_ok当Perl尝试编译调用并且它被炸毁时,该符号不可用.强制eval编译时应该足以使符号可用:

BEGIN {
    eval "use Test::Version";
    plan skip_all => "Test::Version required for testing versions"
        if $@;
}
Run Code Online (Sandbox Code Playgroud)