X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FManual%2FConstruction.pod;h=24689c06bf346f3a6f29988ddb90308b515b3499;hb=794c5045d349100e57cbbb88057aaccc79cdeae9;hp=957dc89bee11e503da15d3c4e33a6a87da686498;hpb=2840a3b25fac3ab606e2053ce9ef30b39687270d;p=gitmo%2FMoose.git diff --git a/lib/Moose/Manual/Construction.pod b/lib/Moose/Manual/Construction.pod index 957dc89..24689c0 100644 --- a/lib/Moose/Manual/Construction.pod +++ b/lib/Moose/Manual/Construction.pod @@ -2,16 +2,16 @@ =head1 NAME -Moose::Manual::Classes - Object construction (and destruction) with Moose +Moose::Manual::Construction - Object construction (and destruction) with Moose =head1 WHERE'S THE CONSTRUCTOR? -B method for your classes!> +B method for your classes!> -When you C in your class, you will become a subclass of -C, which provides a C method for you. If you -follow our recommendations in L and make -your class immutable, then you actually get a class-specific C +When you C in your class, your class becomes a subclass of +L. The L provides a C method for your +class. If you follow our recommendations in L +and make your class immutable, then you actually get a class-specific C method "inlined" in your class. =head1 OBJECT CONSTRUCTION AND ATTRIBUTES @@ -25,7 +25,8 @@ you're ready to start creating objects! =head1 OBJECT CONSTRUCTION HOOKS Moose lets you hook into object construction. You can validate an -object's state, do logging, or maybe allow non-hash(ref) constructor +object's state, do logging, customize construction from parameters which +do not match your attributes, or maybe allow non-hash(ref) constructor arguments. You can do this by creating C and/or C methods. @@ -36,42 +37,43 @@ be called as part of the object construction process. The C method is called as a class method I an object is created. It will receive all of the arguments that were -passed to C I, and is expected to return a hash +passed to C I, and is expected to return a hash reference. This hash reference will be used to construct the object, so it should contain keys matching your attributes' names (well, Cs). -One common use for C is to accomodate a non-hash(ref) +One common use for C is to accommodate a non-hash(ref) calling style. For example, we might want to allow our Person class to be called with a single argument of a social security number, C<< Person->new($ssn) >>. Without a C method, Moose will complain, because it expects a hash or hash reference. We can use the C method to -accomodate this calling style: +accommodate this calling style: - sub BUILDARGS { + around BUILDARGS => sub { + my $orig = shift; my $class = shift; - if ( @_ == 1 && ! ref $_[0] ) { - return { ssn => $_[0] }; + if ( @_ == 1 && !ref $_[0] ) { + return $class->$orig( ssn => $_[0] ); } else { - return $class->SUPER::BUILDARGS(@_); + return $class->$orig(@_); } - } + }; -Note the call to C. This will call the default -C in C. This method handles distinguishing -between a hash reference and a plain hash for you. +Note the call to C<< $class->$orig >>. This will call the default C +in L. This method takes care of distinguishing between a hash +reference and a plain hash for you. =head2 BUILD The C method is called I an object is created. There are -ways to use a C method. One of the most common is to check that -the object state is valid. While we can validate individual attributes -through the use of types, we can't validate the state of a whole -object that way. +several reasons to use a C method. One of the most common is to +check that the object state is valid. While we can validate individual +attributes through the use of types, we can't validate the state of a +whole object that way. sub BUILD { my $self = shift; @@ -91,11 +93,28 @@ object creation. debug( 'Made a new person - SSN = ', $self->ssn, ); } -=head3 BUILD and Parent Classes -The interaction between multiple C methods in an inheritance -hierarchy is different from normal Perl methods. BSUPER::BUILD >>.> +The C method is called with the hash reference of the parameters passed +to the constructor (after munging by C). This gives you a chance to +do something with parameters that do not represent object attributes. + + sub BUILD { + my $self = shift; + my $args = shift; + + $self->add_friend( + My::User->new( + user_id => $args->{user_id}, + ) + ); + } + +=head3 BUILD and parent classes + +The interaction between multiple C methods in an inheritance hierarchy +is different from normal Perl methods. BSUPER::BUILD >>>, nor should you ever apply a method modifier to +C. Moose arranges to have all of the C methods in a hierarchy called when an object is constructed, I methods can only be used for increasing specialization of a class's constraints, so it makes sense -to call the least specific first (also, this is how Perl 6 does it). +to call the least specific C method first. Also, this is how +Perl 6 does it. =head1 OBJECT DESTRUCTION @@ -114,9 +134,29 @@ $self->SUPER::DEMOLISH >>. Moose will arrange for all of the C methods in your hierarchy to be called, from most to least specific. +Each C method is called with a single argument. + In most cases, Perl's built-in garbage collection is sufficient, and you won't need to provide a C method. +=head2 Error Handling During Destruction + +The interaction of object destruction and Perl's global C<$@> and C<$?> +variables can be very confusing. + +Moose always localizes C<$?> when an object is being destroyed. This means +that if you explicitly call C, that exit code will be preserved even if +an object's destructor makes a system call. + +Moose also preserves C<$@> against any C calls that may happen during +object destruction. However, if an object's C method actually dies, +Moose explicitly rethrows that error. + +If you do not like this behavior, you will have to provide your own C +method and use that instead of the one provided by L. You can +do this to preserve C<$@> I capture any errors from object destruction by +creating an error stack. + =head1 AUTHOR Dave Rolsky Eautarch@urth.orgE