目の前に僕らの道がある

勉強会とか、技術的にはまったことのメモ

いつの間にかperlのTest::More::subtestのprototypeが消えてた

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

sub okok {
    ok 1;
}
 
sub okokok {
    ok 1;
}

subtest 'ok' => sub {
    okok;
};
 
my $foo = 1;
subtest 'ng' => ($foo == 1 ? \&okok : \&okokok);
 
done_testing;

こんな超簡略化してますが、こんなテストコードを書いたら2つめのsubtestが古めの環境だとこけることに気がつきました。

% perl -v
 
This is perl, v5.10.0 built for x86_64-linux-gnu-thread-multi
 
 
% perldoc -m Test::More| grep VERSION
our $VERSION = '0.96';
 
% perl subtest.pl
Type of arg 2 to Test::More::subtest must be sub {} (not null operation) at subtest.pl line 18, near ");"
Execution of subtest.pl aborted due to compilation errors.

で、手元のmacで確認してみるちゃんと通ります。

% perl -v 
 
This is perl 5, version 14, subversion 2 (v5.14.2) built for darwin-2level
 
% perldoc -m Test::More | grep VERSION
our $VERSION = '0.98';
 
% perl subtest.pl
    ok 1
    1..1
ok 1 - ok
    ok 1
    1..1
ok 2 - ng
1..2

ちょろっと調べて見るとどうやらv0.97からsubtestのprototypeが消えていたようです。
ふむー。

subtest() no longer has a prototype. It was just getting in the way.

http://search.cpan.org/diff?from=Test-Simple-0.96&to=Test-Simple-0.97_01

まー、素直にif文で分岐するか&をつけてprototypeを無視すればいいんですけどね。
(そもそも、テストにロジックをいれるのが間違っているといわれればそうなんですが。

subtest 'ng' => sub {
    if ($foo == 1) {
        okok();
    }
    else {
        okokok();
    }
};
&subtest('ng' => ($foo == 1 ? \&okok : \&okokok));