=pod =head1 NAME Moose::Cookbook::Recipe9 - Builder methods and lazy_build =head1 SYNOPSIS package BinaryTree; use Moose; has 'node' => (is => 'rw', isa => 'Any'); has 'parent' => ( is => 'rw', isa => 'BinaryTree', predicate => 'has_parent', weak_ref => 1, ); has 'left' => ( is => 'rw', isa => 'BinaryTree', predicate => 'has_left', lazy => 1, builder => '_build_child_tree', ); has 'right' => ( is => 'rw', isa => 'BinaryTree', predicate => 'has_right', lazy => 1, builder => '_build_child_tree', ); before 'right', 'left' => sub { my ($self, $tree) = @_; $tree->parent($self) if defined $tree; }; sub _build_child_tree { my $self = shift; return BinaryTree->new( parent => $self ); } =head1 DESCRIPTION If you've already read L, then this example should look awfully familiar. In fact, all we've done here is replace the attribute C with a C method. In this particular case, the C and C options act in exactly the same way. When the C or C attribute get method is called, Moose will call the builder method to initialize the attribute. Note that Moose calls the builder method I. Here's an example in code: my $tree = BinaryTree->new(); my $left = $tree->left(); At this point, Moose will call C<< $tree->_build_child_tree() >> in order to populate the C attribute. If we had passed C to the original constructor, the builer would not be called. =head2 Subclassable There are some differences between C and C. Because C is called I, it goes through Perl's normal inheritance system. This means that builder methods are both inheritable and overrideable. For example, we might make a C subclass: package TrinaryTree; use Moose; extends 'BinaryTree'; has 'middle' => ( is => 'rw', isa => 'BinaryTree', predicate => 'has_middle', lazy => 1, builder => '_build_child_tree', ); This doesn't quite work though. If you look closely at the C<_build_child_tree> method defined in C, you'll notice that it hard-codes a class name. Naughty us! Also, as a bonus, we'll pass C<@_> through, so subclasses can override the method to pass additional options to the constructor. Good object-oriented code should allow itself to be subclassed gracefully. Let's tweak C<_build_child_tree>: sub _build_child_tree { my $self = shift; return (ref $self)->new( parent => $self, @_ ); } Now C<_build_child_tree> can be gracefully inherited and overridden. =head2 Composable There's more to builders than just subclassing, though. The fact that builders are called by name also makes them suitable for use in a role. package HasAnimal; use Moose::Role; requires '_build_animal'; has 'animal' => ( is => 'ro', isa => 'Animal', lazy => 1, builder => '_build_animal', ); This role provides an animal attribute, but requires that the consumer of the role provide a builder method it. package CatLover; use Moose; with 'HasAnimal'; sub _build_animal { return Cat->new(); } =head2 The lazy_build shortcut The C attribute parameter can be used as sugar to specify a whole bunch of options at once. has 'animal' => ( is => 'ro', isa => 'Animal', lazy_build => 1, ); This is a shorthand for this: has 'animal' => ( is => 'ro', isa => 'Animal', required => 1, lazy => 1, builder => '_build_animal', predicate => 'has_animal', clearer => 'clear_animal', ); If your attribute starts with an underscore, Moose is smart and will do the right thing with the C and C, making them both start with an underscore. The C method I starts with an underscore, since you will want this to be private the vast majority of the time. Note that the C method name is created by simply taking "_build_" and appending the attribute name. This means that attributes with a leading underscore like C<_animal> end up with a builder named C<_build__animal>. =head1 CONCLUSION The C option is a more OO-friendly version of the C functionality. It also has the property of separating out the code into a separate well-defined method. This alone makes it valuable. It is quite ugly to jam a long default code reference into your attribute definition. Here are some good rules for determining when to use C vs C. If the default value is a simple scalar that only needs to be calculated once (or a constant), use C. If the default value is an empty reference that needs to be wrapped in a coderef like C, use C. Otherwise, use C. This ensures that your classes are easily subclassable, and also helps keep crufty code out of your attribute definition blocks. =head1 AUTHOR Dave Rolsky Eautarch@urth.orgE =head1 COPYRIGHT AND LICENSE Copyright 2006-2008 by Infinity Interactive, Inc. L This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut