summaryrefslogtreecommitdiff
path: root/lib/Moose/Cookbook/Basics/Person_BUILDARGSAndBUILD.pod
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Moose/Cookbook/Basics/Person_BUILDARGSAndBUILD.pod')
-rw-r--r--lib/Moose/Cookbook/Basics/Person_BUILDARGSAndBUILD.pod180
1 files changed, 180 insertions, 0 deletions
diff --git a/lib/Moose/Cookbook/Basics/Person_BUILDARGSAndBUILD.pod b/lib/Moose/Cookbook/Basics/Person_BUILDARGSAndBUILD.pod
new file mode 100644
index 0000000..5262d06
--- /dev/null
+++ b/lib/Moose/Cookbook/Basics/Person_BUILDARGSAndBUILD.pod
@@ -0,0 +1,180 @@
+# PODNAME: Moose::Cookbook::Basics::Person_BUILDARGSAndBUILD
+# ABSTRACT: Using BUILDARGS and BUILD to hook into object construction
+
+__END__
+
+=pod
+
+=encoding UTF-8
+
+=head1 NAME
+
+Moose::Cookbook::Basics::Person_BUILDARGSAndBUILD - Using BUILDARGS and BUILD to hook into object construction
+
+=head1 VERSION
+
+version 2.1405
+
+=head1 SYNOPSIS
+
+ package Person;
+
+ has 'ssn' => (
+ is => 'ro',
+ isa => 'Str',
+ predicate => 'has_ssn',
+ );
+
+ has 'country_of_residence' => (
+ is => 'ro',
+ isa => 'Str',
+ default => 'usa'
+ );
+
+ has 'first_name' => (
+ is => 'ro',
+ isa => 'Str',
+ );
+
+ has 'last_name' => (
+ is => 'ro',
+ isa => 'Str',
+ );
+
+ around BUILDARGS => sub {
+ my $orig = shift;
+ my $class = shift;
+
+ if ( @_ == 1 && ! ref $_[0] ) {
+ return $class->$orig(ssn => $_[0]);
+ }
+ else {
+ return $class->$orig(@_);
+ }
+ };
+
+ sub BUILD {
+ my $self = shift;
+
+ if ( $self->country_of_residence eq 'usa' ) {
+ die 'Cannot create a Person who lives in the USA without an ssn.'
+ unless $self->has_ssn;
+ }
+ }
+
+=head1 DESCRIPTION
+
+This recipe demonstrates the use of C<BUILDARGS> and C<BUILD>. By
+defining these methods, we can hook into the object construction
+process without overriding C<new>.
+
+The C<BUILDARGS> method is called I<before> an object has been
+created. It is called as a class method, and receives all of the
+parameters passed to the C<new> method. It is expected to do something
+with these arguments and return a hash reference. The keys of the hash
+must be attribute C<init_arg>s.
+
+The primary purpose of C<BUILDARGS> is to allow a class to accept
+something other than named arguments. In the case of our C<Person>
+class, we are allowing it to be called with a single argument, a
+social security number:
+
+ my $person = Person->new('123-45-6789');
+
+The key part of our C<BUILDARGS> is this conditional:
+
+ if ( @_ == 1 && ! ref $_[0] ) {
+ return $class->$orig(ssn => $_[0]);
+ }
+
+By default, Moose constructors accept a list of key-value pairs, or a
+hash reference. We need to make sure that C<$_[0]> is not a reference
+before assuming it is a social security number.
+
+We call the original C<BUILDARGS> method to handle all the other
+cases. You should always do this in your own C<BUILDARGS> methods,
+since L<Moose::Object> provides its own C<BUILDARGS> method that
+handles hash references and a list of key-value pairs.
+
+The C<BUILD> method is called I<after> the object is constructed, but
+before it is returned to the caller. The C<BUILD> method provides an
+opportunity to check the object state as a whole. This is a good place
+to put logic that cannot be expressed as a type constraint on a single
+attribute.
+
+In the C<Person> class, we need to check the relationship between two
+attributes, C<ssn> and C<country_of_residence>. We throw an exception
+if the object is not logically consistent.
+
+=head1 MORE CONSIDERATIONS
+
+This recipe is made significantly simpler because all of the
+attributes are read-only. If the C<country_of_residence> attribute
+were settable, we would need to check that a Person had an C<ssn> if
+the new country was C<usa>. This could be done with a C<before>
+modifier.
+
+=head1 CONCLUSION
+
+We have repeatedly discouraged overriding C<new> in Moose
+classes. This recipe shows how you can use C<BUILDARGS> and C<BUILD>
+to hook into object construction without overriding C<new>.
+
+The C<BUILDARGS> method lets us expand on Moose's built-in parameter
+handling for constructors. The C<BUILD> method lets us implement
+logical constraints across the whole object after it is created.
+
+=head1 AUTHORS
+
+=over 4
+
+=item *
+
+Stevan Little <stevan.little@iinteractive.com>
+
+=item *
+
+Dave Rolsky <autarch@urth.org>
+
+=item *
+
+Jesse Luehrs <doy@tozt.net>
+
+=item *
+
+Shawn M Moore <code@sartak.org>
+
+=item *
+
+יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
+
+=item *
+
+Karen Etheridge <ether@cpan.org>
+
+=item *
+
+Florian Ragwitz <rafl@debian.org>
+
+=item *
+
+Hans Dieter Pearcey <hdp@weftsoar.net>
+
+=item *
+
+Chris Prather <chris@prather.org>
+
+=item *
+
+Matt S Trout <mst@shadowcat.co.uk>
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+This software is copyright (c) 2006 by Infinity Interactive, Inc..
+
+This is free software; you can redistribute it and/or modify it under
+the same terms as the Perl 5 programming language system itself.
+
+=cut