I've gotten a couple of emails from folks about the annoying "too late to run INIT block" error which comes up when using Class::Trait. Due to how Perl works, there's not much which can be done about it, but here's one way I've dealt with it in my Test::Class base class:
sub startup : Test(startup) {
my $test = shift;
# If there are any tests in this class using the db, set it up:
if($test->_pkg_has_attribute('DB')) {
$test->_database( TEST::Database->new );
}
{
my $using_traits = 0;
# Because of how traits work, they need to be loaded at compile time
# or else their integrity checks fail. This skips their warning and
# runs the integrity checks manually if traits are used.
local $SIG{__WARN__} = sub {
my $warning = shift;
if ( $warning =~ /Too late to run INIT block.*Class\/Trait.pm/ ) {
$using_traits = 1;
return;
}
CORE::warn($warning);
};
my $class = $test->_class;
$class->require or $test->FAIL_ALL("Could not require $class: $@");
Class::Trait->initialize if $using_traits;
}
}