oop intermediate

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

  • has defines the attribute config with three options:
    • lazy => 1 delays 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 of lazy_build => 1.
  • This approach is fully supported in core Moo and avoids runtime errors.
  • Data::Dumper is used to print the attribute structure, and is properly imported.

Common Pitfalls

  • Assuming lazy_build is built into Moo causes missing clearer methods.
  • Builder methods must be named exactly as given in the builder option (underscore prefix is common).
  • Not providing a clearer method means you cannot clear the cached value for rebuild.
  • Always import or fully qualify Dumper to 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

Tip: edit code and use “Run (Browser)”. Server runs always execute the published, verified snippet.
STDOUT
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'
        };
STDERR
(empty)

Was this helpful?

Related Questions