
=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<Moose::Cookbook::Recipe3>, then this example
should look awfully familiar. In fact, all we've done here is replace
the attribute C<default> with a C<builder> method.

In this particular case, the C<default> and C<builder> options act in
exactly the same way. When the C<left> or C<right> attribute get
method is called, Moose will call the builder method to initialize the
attribute.

Note that Moose calls the builder method I<on the object which has the
attribute>. 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<left> attribute. If we had passed C<left> to
the original constructor, the builer would not be called.

=head2 Subclassable

There are some differences between C<default> and C<builder>. Because
C<builder> is called I<by name>, 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<BinaryTree> 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<BinaryTree>, 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<lazy_build> 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<predicate> and C<clearer>, making them
both start with an underscore. The C<builder> method I<always> starts
with an underscore, since you will want this to be private the vast
majority of the time.

Note that the C<builder> 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<builder> option is a more OO-friendly version of the C<default>
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<builder> vs
C<default>.

If the default value is a simple scalar that only needs to be
calculated once (or a constant), use C<default>.

If the default value is an empty reference that needs to be wrapped in
a coderef like C<sub { [] }>, use C<default>.

Otherwise, use C<builder>.

This ensures that your classes are easily subclassable, and also helps
keep crufty code out of your attribute definition blocks.

=head1 AUTHOR

Dave Rolsky E<lt>autarch@urth.orgE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright 2006-2008 by Infinity Interactive, Inc.

L<http://www.iinteractive.com>

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.

=cut
