I am new to Perl. I find out that code as follows cannot run:
#! perl -T
use strict;
use warnings;
BEGIN {
my @classes = qw(Animal Cow Sheep Horse Mouse);
use Test::More tests => scalar @classes;
}
If I change scalar @classes to 5, it is ok. If I change use Test::More tests => scalar @classes; to print scalar @classes;, it is ok. But when they are together, they are wrong. Why?
The idiomatic way to do this would be to use the plan function instead of specifying the number of tests in the use statement:
use Test::More;
my @classes = qw(Animal Cow Sheep Horse Mouse);
plan(tests => scalar @classes);
If you insist on specifying the number of tests in the use, you need either
my @classes;
BEGIN {
@classes = qw(Animal Cow Sheep Horse Mouse);
}
use Test::More tests => scalar @classes;
or
BEGIN {
my @classes = qw(Animal Cow Sheep Horse Mouse);
require Test::More;
Test::More->import(tests => scalar @classes);
}
The problem is that use is evaluated at compile-time. You put it inside a BEGIN block, which is also evaluated at compile-time, but the BEGIN block has its own compilation phase.
Because the use is executed before the rest of the BEGIN block, what you wrote is equivalent to
BEGIN {
my @classes;
require Test::More;
Test::More->import(tests => scalar @classes);
@classes = qw(Animal Cow Sheep Horse Mouse)
}
That's why it complains about you trying to plan 0 tests.
This is because use MODULE is exactly equivalent to BEGIN { require Module; Module->import( LIST ); } (see perldoc -f use).
I suspect the BEGIN within a a BEGIN block is causing the problem, and indeed, replacing the code with
#! perl -T
use strict;
use warnings;
BEGIN {
my @classes = qw(Animal Cow Sheep Horse Mouse);
require Test::More; Test::More->import( tests => scalar @classes );
}
seems work fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With