由于标量@list,Perl BEGIN编译失败

rog*_*ger 3 perl

我是Perl的新手.我发现以下代码无法运行:

#! perl -T

use strict;
use warnings;

BEGIN {
    my @classes = qw(Animal Cow Sheep Horse Mouse);
    use Test::More tests => scalar @classes;
}
Run Code Online (Sandbox Code Playgroud)

如果我换scalar @classes5,那没关系.如果我换use Test::More tests => scalar @classes;print scalar @classes;,那没关系.但是当他们在一起时,他们错了.为什么?

cjm*_*cjm 7

执行此操作的惯用方法是使用plan函数而不是在use语句中指定测试数:

use Test::More;
my @classes = qw(Animal Cow Sheep Horse Mouse);
plan(tests => scalar @classes);
Run Code Online (Sandbox Code Playgroud)

如果你坚持指定测试的数量use,你需要

my @classes;
BEGIN {
    @classes = qw(Animal Cow Sheep Horse Mouse);
}
use Test::More tests => scalar @classes;
Run Code Online (Sandbox Code Playgroud)

要么

BEGIN {
    my @classes = qw(Animal Cow Sheep Horse Mouse);
    require Test::More;
    Test::More->import(tests => scalar @classes);
}
Run Code Online (Sandbox Code Playgroud)

问题是use在编译时进行评估.你把它放在一个BEGIN块中,它也在编译时进行评估,但BEGIN块有自己的编译阶段.

因为在块use的其余部分之前执行BEGIN,所写的内容相当于

BEGIN {
    my @classes;
    require Test::More;
    Test::More->import(tests => scalar @classes);
    @classes = qw(Animal Cow Sheep Horse Mouse)
}
Run Code Online (Sandbox Code Playgroud)

这就是为什么它抱怨你试图计划0测试.