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