Don't use base.pm, use parent.pm instead! を踏んじゃったお話です。
結論
古いPerlを使っていたらbaseのバグを踏んだ。
問題となったbaseのバージョン(2.16)はCPANには存在せず、下記のPerlバージョンに含まれているbaseでだけ問題になります。
baseのバージョンをあげるか、parentを使いましょう。
$ corelist -a base | grep '2\.16'
v5.13.11 2.16
v5.14.0 2.16
v5.14.1 2.16
v5.14.2 2.16
v5.14.3 2.16
v5.14.4 2.16
気づいたきっかけはTest::Harness
$ prove --harness TAP::Harness::JUnit
Can’t locate object method “new” via package “TAP::Harness::JUnit::SUPER” at hoge/TAP/Harness/JUnit.pm line 145.
harnessオプションで指定したモジュールの親クラスがロードできていません。
App::Prove
のrequire_harness
とprint_version
メソッドにbaseのバグを踏むコードがあるのですが、ここではシンプルに下記の再現コードを記載します。
package Foo;
use base 'FooBase';
sub new {FooBase->new;}
1;
package FooBase;
sub new {print "FooBase\n";}
1;
$FooBase::VERSION;
use Foo;
Foo->new;
本来ならFoo->new
を呼び出せばFooの中でFooBase->new
が呼び出されますが、baseのバグにより、Can't locate object method "new" via package "FooBase"と言われてしまいます。
use Foo;
より前に親クラスの$FooBase::VERSION
が記述してあると発生します。
追記
Test::Harnessのバージョン3.31未満だとエラーになりません