Как насчет:
lazy => 1,
default => sub { confess "not set" },
Возможно, вы также захотите добавить предикат:
predicate => 'has_optional_attr',
чтобы вы могли узнать, установлен ли он, не умирая.
Также есть MooseX :: LazyRequire , что позволяет вам просто сказать:
use MooseX::LazyRequire;
has 'optional_attr' => (
is => 'ro',
isa => 'MyCoolType',
lazy_required => 1,
);
Под капотом используется тот же трюк, который я предложил, но в вашем классе он выглядит более элегантно.