Builders are in recipe 8, not 9
[gitmo/Moose.git] / lib / Moose / Cookbook / Basics / Recipe10.pod
CommitLineData
c2a0627f 1
2=pod
3
4=head1 NAME
5
ec65165a 6Moose::Cookbook::Basics::Recipe10 - Using BUILDARGS and BUILD to hook into object construction
c2a0627f 7
8=head1 SYNOPSIS
9
1f476b5f 10 package Person;
c765b254 11
1f476b5f 12 has 'ssn' => (
13 is => 'ro',
14 isa => 'Str',
15 predicate => 'has_ssn',
16 );
c765b254 17
1f476b5f 18 has 'country_of_residence' => (
19 is => 'ro',
20 isa => 'Str',
21 default => 'usa'
22 );
c765b254 23
1f476b5f 24 has 'first_name' => (
25 is => 'ro',
26 isa => 'Str',
27 );
c765b254 28
1f476b5f 29 has 'last_name' => (
30 is => 'ro',
31 isa => 'Str',
32 );
c765b254 33
1f476b5f 34 sub BUILDARGS {
35 my $class = shift;
c765b254 36
1f476b5f 37 if ( @_ == 1 && ! ref $_[0] ) {
38 return { ssn => $_[0] };
39 }
40 else {
41 return $class->SUPER::BUILDARGS(@_);
42 }
c2a0627f 43 }
44
1f476b5f 45 sub BUILD {
46 my $self = shift;
c765b254 47
1f476b5f 48 if ( $self->country_of_residence eq 'usa' ) {
49 die 'Cannot create a Person who lives in the USA without an ssn.'
50 unless $self->has_ssn;
51 }
c2a0627f 52 }
53
1f476b5f 54=head1 DESCRIPTION
c2a0627f 55
1f476b5f 56This recipe demonstrates the use of C<BUILDARGS> and C<BUILD>. By
57defining these methods, we can hook into the object construction
58process without overriding C<new>.
c765b254 59
1f476b5f 60The C<BUILDARGS> method is called I<before> an object has been
61created. It is called as a class method, and receives all of the
62parameters passed to the C<new> method. It is expected to do something
63with these arguments and return a hash reference. The keys of the hash
64must be attribute C<init_arg>s.
c765b254 65
1f476b5f 66The primary purpose of C<BUILDARGS> is to allow a class to accept
67something other than named arguments. In the case of our C<Person>
68class, we are allowing it to be called with a single argument, a
69social security number:
c765b254 70
1f476b5f 71 my $person = Person->new('123-45-6789');
c765b254 72
1f476b5f 73The key part of our C<BUILDARGS> is this conditional:
c765b254 74
1f476b5f 75 if ( @_ == 1 && ! ref $_[0] ) {
76 return { ssn => $_[0] };
77 }
c2a0627f 78
1f476b5f 79By default, Moose constructors accept a list of key-value pairs, or a
80hash reference. We need to make sure that C<$_[0]> is not a reference
81before assuming it is a social security number.
c2a0627f 82
1f476b5f 83We call C<< $class->SUPER::BUILDARGS(@_) >> to handle all the other
84cases. You should always do this in your own C<BUILDARGS> methods,
85since L<Moose::Object> provides its own C<BUILDARGS> method that
86handles hash references and a list of key-value pairs.
c2a0627f 87
1f476b5f 88The C<BUILD> method is called I<after> the object is constructed, but
89before it is returned to the caller. The C<BUILD> method provides an
90opportunity to check the object state as a whole. This is a good place
91to put logic that cannot be expressed as a type constraint on a single
92attribute.
c2a0627f 93
1f476b5f 94In the C<Person> class, we need to check the relationship between two
95attributes, C<ssn> and C<country_of_residence>. We throw an exception
96if the object is not logically consistent.
c765b254 97
1f476b5f 98=head1 MORE CONSIDERATIONS
c765b254 99
1f476b5f 100This recipe is made significantly simpler because all of the
101attributes are read-only. If the C<country_of_residence> attribute
102were settable, we would need to check that a Person had an C<ssn> if
103the new country was C<usa>. This could be done with a C<before>
104modifier.
c2a0627f 105
106=head1 CONCLUSION
107
1f476b5f 108We have repeatedly discouraged overriding C<new> in Moose
109classes. This recipe shows how you can use C<BUILDARGS> and C<BUILD>
110to hook into object construction without overriding C<new>
c2a0627f 111
1f476b5f 112The C<BUILDARGS> method lets us expand on Moose's built-in parameter
113handling for constructors. The C<BUILD> method lets us implement
114logical constraints across the whole object after it is created.
c2a0627f 115
1f476b5f 116=head1 AUTHOR
c2a0627f 117
055dbe8c 118Dave Rolsky E<lt>autarch@urth.orgE<gt>
119
1f476b5f 120=head1 COPYRIGHT AND LICENSE
c2a0627f 121
1f476b5f 122Copyright 2006-2009 by Infinity Interactive, Inc.
c2a0627f 123
1f476b5f 124L<http://www.iinteractive.com>
c2a0627f 125
1f476b5f 126This library is free software; you can redistribute it and/or modify
127it under the same terms as Perl itself.
c2a0627f 128
1f476b5f 129=cut