How to use Moo lazy_build for attribute defaults in Perl?
Question
How to use Moo lazy_build for attribute defaults in Perl?
The issue arises because lazy_build is not a core feature of Moo itself; it comes from the helper module MooX::LazyBuild. Without loading this module, the clear_config method is not auto-generated, resulting in the runtime error Can't locate object method "clear_config".
To safely use a lazy builder with Moo without additional modules, you can explicitly specify lazy => 1, provide a builder, and optionally a clearer method yourself. This manual approach replicates what lazy_build automates.
Working Example With Manual Lazy Builder Setup in Moo
use strict;
use warnings;
use Data::Dumper;
{
package MyClass;
use Moo;
# Define 'config' as lazy with manual builder and clearer
has 'config' => (
is => 'rw',
lazy => 1,
builder => '_build_config',
clearer => 'clear_config',
);
# Builder method must be named _build_config
sub _build_config {
print "Building config attribute...\n";
return { key => "value", timestamp => time };
}
}
# Main script demonstration
my $obj = MyClass->new();
print "Object created, config not built yet.\n\n";
print "Accessing config first time:\n";
my $conf = $obj->config;
print Dumper($conf);
print "Accessing config second time (cached, no rebuild):\n";
print Dumper($obj->config);
print "Clearing config cache...\n";
$obj->clear_config;
print "Accessing config after clearing (rebuild occurs):\n";
print Dumper($obj->config);
Explanation
hasdefines the attributeconfigwith three options:lazy => 1delays building the attribute until first access.builder => '_build_config'specifies the method to call for the default value.clearer => 'clear_config'creates a method to clear the cached value, forcing rebuild on next access.
- Without
MooX::LazyBuild, you must manually set these options yourself instead oflazy_build => 1. - This approach is fully supported in core
Mooand avoids runtime errors. Data::Dumperis used to print the attribute structure, and is properly imported.
Common Pitfalls
- Assuming
lazy_buildis built intoMoocauses missing clearer methods. - Builder methods must be named exactly as given in the
builderoption (underscore prefix is common). - Not providing a
clearermethod means you cannot clear the cached value for rebuild. - Always import or fully qualify
Dumperto avoid runtime errors.
This example is runnable as-is with perl - and meets your constraints—no external modules, no file or network I/O, and runs instantly. Using manual lazy builder setup with Moo ensures compatibility and control.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 40ms
Object created, config not built yet.
Accessing config first time:
Building config attribute...
$VAR1 = {
'timestamp' => 1767068731,
'key' => 'value'
};
Accessing config second time (cached, no rebuild):
$VAR1 = {
'timestamp' => 1767068731,
'key' => 'value'
};
Clearing config cache...
Accessing config after clearing (rebuild occurs):
Building config attribute...
$VAR1 = {
'timestamp' => 1767068731,
'key' => 'value'
};
(empty)Was this helpful?
Related Questions
- How to use Moose::Util::TypeConstraints for custom types?
- How to implement method delegation in Perl Moo?
- How to use Type::Tiny with Moo for strict typing in Perl?
- How to use required attributes in Perl Moo and Moose?
- How to convert a Perl Moo class to Moose?
- How to implement multiple inheritance with Moose in Perl?