X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FManual%2FAttributes.pod;h=ff5af8b61aa5cdb77e3cc8e44c74fea694bed504;hb=0e8cddd7b18ca15aaa2773af593977618532dc8d;hp=8dff639e243436b8a1290980b2a9441a84806f8e;hpb=d76a67a8a9cf4fa39151d1657b02eb7bfc1b8886;p=gitmo%2FMoose.git diff --git a/lib/Moose/Manual/Attributes.pod b/lib/Moose/Manual/Attributes.pod index 8dff639..ff5af8b 100644 --- a/lib/Moose/Manual/Attributes.pod +++ b/lib/Moose/Manual/Attributes.pod @@ -1,8 +1,10 @@ -=pod +package Moose::Manual::Attributes; + +# ABSTRACT: Object attributes with Moose -=head1 NAME +__END__ -Moose::Manual::Attributes - Object attributes with Moose +=pod =head1 INTRODUCTION @@ -38,14 +40,19 @@ This says that all C objects have an optional read-write =head2 Read-write vs. read-only -The options passed to C define the properties of the -attribute. There are many options, but in the simplest form you just -need to set C, which can be either C (read-write) or C -(read-only). +The options passed to C define the properties of the attribute. There are +many options, but in the simplest form you just need to set C, which can +be either C (read-only) or C (read-write). When an attribute is C, +you can change it by passing a value to its accessor. When an attribute is +C, you may only read the current value of the attribute. -(In fact, you could even omit C, but that gives you an attribute -that has no accessors, which is pointless unless you're doing some -deep, dark magic). +In fact, you could even omit C, but that gives you an attribute +that has no accessor. This can be useful with other attribute options, +such as C. However, if your attribute generates I +accessors, Moose will issue a warning, because that usually means the +programmer forgot to say the attribute is read-only or read-write. If +you really mean to have no accessors, you can silence this warning by +setting C to C. =head2 Accessor methods @@ -205,18 +212,18 @@ reference will be called as a method on the object. predicate => 'has_size', ); -This is dumb example, but it illustrates the point that the subroutine +This is a trivial example, but it illustrates the point that the subroutine will be called for every new object created. When you provide a C subroutine reference, it is called as a method on the object, with no additional parameters: has 'size' => ( - is => 'ro', + is => 'ro', default => sub { my $self = shift; - return $self->height > 200 ? 'big' : 'average'; + return $self->height > 200 ? 'large' : 'average'; }, ); @@ -226,9 +233,15 @@ dependent on other parts of the object's state, you can make the attribute C. Laziness is covered in the next section. If you want to use a reference of any sort as the default value, you -must return it from a subroutine. This is necessary because otherwise -Perl would instantiate the reference exactly once, and it would be -shared by all objects: +must return it from a subroutine. + + has 'mapping' => ( + is => 'ro', + default => sub { {} }, + ); + +This is necessary because otherwise Perl would instantiate the reference +exactly once, and it would be shared by all objects: has 'mapping' => ( is => 'ro', @@ -240,17 +253,12 @@ as the default. If Moose allowed this then the default mapping attribute could easily end up shared across many objects. Instead, wrap it in a subroutine -reference: - - has 'mapping' => ( - is => 'ro', - default => sub { {} }, # right! - ); +reference as we saw above. This is a bit awkward, but it's just the way Perl works. -As an alternative to using a subroutine reference, you can instead -supply a C method for your attribute: +As an alternative to using a subroutine reference, you can supply a C +method for your attribute: has 'size' => ( is => 'ro', @@ -262,9 +270,9 @@ supply a C method for your attribute: return ( 'small', 'medium', 'large' )[ int( rand 3 ) ]; } -This has several advantages. First, it moves a chunk of code to its -own named method, which improves readability and code -organization. +This has several advantages. First, it moves a chunk of code to its own named +method, which improves readability and code organization. Second, because this +is a I method, it can be subclassed or provided by a role. We strongly recommend that you use a C instead of a C for anything beyond the most trivial default. @@ -287,7 +295,7 @@ If we subclass our C class, we can override C<_build_size>: sub _build_size { return 'small' } -=head3 Builders can be composed from roles +=head3 Builders work well with roles Because builders are called by name, they work well with roles. For example, a role could provide an attribute but require that the @@ -313,7 +321,7 @@ consuming class provide the C: Roles are covered in L. -=head2 Laziness and C +=head2 Laziness Moose lets you defer attribute population by making an attribute C: @@ -342,58 +350,6 @@ some CPU time. We recommend that you make any attribute with a builder or non-trivial default C as a matter of course. -To facilitate this, you can simply specify the C attribute -option. This bundles up a number of options together: - - has 'size' => ( - is => 'ro', - lazy_build => 1, - ); - -This is the same as specifying all of these options: - - has 'size' => ( - is => 'ro', - lazy => 1, - builder => '_build_size', - clearer => 'clear_size', - predicate => 'has_size', - ); - -If your attribute name starts with an underscore (C<_>), then the clearer -and predicate will as well: - - has '_size' => ( - is => 'ro', - lazy_build => 1, - ); - -becomes: - - has '_size' => ( - is => 'ro', - lazy => 1, - builder => '_build__size', - clearer => '_clear_size', - predicate => '_has_size', - ); - -Note the doubled underscore in the builder name. Internally, Moose -simply prepends the attribute name with "_build_" to come up with the -builder name. - -If you don't like the names that C generates, you can -always provide your own: - - has 'size' => ( - is => 'ro', - lazy_build => 1, - clearer => '_clear_size', - ); - -Options that you explicitly provide are always used in favor of -Moose's internal defaults. - =head2 Constructor parameters (C) By default, each attribute can be passed by name to the class's @@ -401,7 +357,7 @@ constructor. On occasion, you may want to use a different name for the constructor parameter. You may also want to make an attribute unsettable via the constructor. -Both of these goals can be accomplished with the C option: +You can do either of these things with the C option: has 'bigness' => ( is => 'ro', @@ -415,9 +371,10 @@ Even more useful is the ability to disable setting an attribute via the constructor. This is particularly handy for private attributes: has '_genetic_code' => ( - is => 'ro', - lazy_build => 1, - init_arg => undef, + is => 'ro', + lazy => 1, + builder => '_build_genetic_code', + init_arg => undef, ); By setting the C to C, we make it impossible to set @@ -439,6 +396,15 @@ C whenever the attribute is set: This is very useful when you're building objects that may contain circular references. +When the object in a weak references goes out of scope, the attribute's value +will become C "behind the scenes". This is done by the Perl interpreter +directly, so Moose does not see this change. This means that triggers don't +fire, coercions aren't applied, etc. + +The attribute is not cleared, so a predicate method for that attribute will +still return true. Similarly, when the attribute is next accessed, a default +value will not be generated. + =head2 Triggers A C is a subroutine that is called whenever the attribute is @@ -450,13 +416,23 @@ set: ); sub _size_set { - my ( $self, $size ) = @_; + my ( $self, $size, $old_size ) = @_; - warn $self->name, " size is now $size\n"; + my $msg = $self->name; + + if ( @_ > 2 ) { + $msg .= " - old size was $old_size"; + } + + $msg .= " - size is now $size"; + warn $msg; } -The trigger is called as a method, and receives the new value as its argument. -The trigger is called I the value is set. +The trigger is called I an attribute's value is set. It is +called as a method on the object, and receives the new and old values as +its arguments. If the attribute had not previously been set at all, +then only the new value is passed. This lets you distinguish between +the case where the attribute had no value versus when the old value was C. This differs from an C method modifier in two ways. First, a trigger is only called when the attribute is set, as opposed to @@ -506,26 +482,12 @@ $self->hair_color->as_hex_string >>. See L for documentation on how to set up delegation methods. -=head2 Metaclass and traits - -One of Moose's best features is that it can be extended in all sorts -of ways through the use of custom metaclasses and metaclass traits. +=head2 Attribute traits and metaclasses -When declaring an attribute, you can declare a metaclass or a set of -traits for the attribute: +One of Moose's best features is that it can be extended in all sorts of ways +through the use of metaclass traits and custom metaclasses. - use MooseX::AttributeHelpers; - - has 'mapping' => ( - metaclass => 'Collection::Hash', - is => 'ro', - default => sub { {} }, - ); - -In this case, the metaclass C really refers to -L. - -You can also apply one or more traits to an attribute: +You can apply one or more traits to an attribute: use MooseX::MetaDescription; @@ -546,37 +508,36 @@ attribute metaclasses and traits. See L for some examples. You can also write your own metaclasses and traits. See the "Meta" and "Extending" recipes in L for examples. -=head1 ATTRIBUTE INHERITANCE +=head2 Native Delegations -By default, a child inherits all of its parent class(es)' attributes -as-is. However, you can explicitly change some aspects of the -inherited attribute in the child class. +Native delegations allow you to delegate to standard Perl data structures as +if they were objects. -The options that can be overridden in a subclass are: +For example, we can pretend that an array reference has methods like +C, C, C, C, and more. -=over 4 - -=item * default - -=item * coerce - -=item * required - -=item * documentation - -=item * lazy - -=item * isa - -=item * handles - -=item * builder + has 'options' => ( + traits => ['Array'], + is => 'ro', + isa => 'ArrayRef[Str]', + default => sub { [] }, + handles => { + all_options => 'elements', + add_option => 'push', + map_options => 'map', + option_count => 'count', + sorted_options => 'sort', + }, + ); -=item * metaclass +See L for more details. -=item * traits +=head1 ATTRIBUTE INHERITANCE -=back +By default, a child inherits all of its parent class(es)' attributes +as-is. However, you can change most aspects of the inherited attribute in the +child class. You cannot change any of its associated method names (reader, +writer, predicate, etc). To override an attribute, you simply prepend its name with a plus sign (C<+>): @@ -598,6 +559,24 @@ to C<'Bill'>. We recommend that you exercise caution when changing the type (C) of an inherited attribute. +=head1 MULTIPLE ATTRIBUTE SHORTCUTS + +If you have a number of attributes that differ only by name, you can declare +them all at once: + + package Point; + + use Moose; + + has [ 'x', 'y' ] => ( is => 'ro', isa => 'Int' ); + +Also, because C is just a function call, you can call it in a loop: + + for my $name ( qw( x y ) ) { + my $builder = '_build_' . $name; + has $name => ( is => 'ro', isa => 'Int', builder => $builder ); + } + =head1 MORE ON ATTRIBUTES Moose attributes are a big topic, and this document glosses over a few @@ -634,30 +613,14 @@ returned from the reader method: This option only works if your attribute is explicitly typed as an C or C. -However, we recommend that you use L for -these types of attributes, which gives you much more control over how +However, we recommend that you use L traits +for these types of attributes, which gives you much more control over how they are accessed and manipulated. =head2 Initializer -Moose provides an attribute option called C. This is -similar to C, except that it is I called during object -construction. - -This option is inherited from L, but we recommend that you -use a C (which is Moose-only) instead. - -=head1 AUTHOR - -Dave Rolsky Eautarch@urth.orgE - -=head1 COPYRIGHT AND LICENSE - -Copyright 2009 by Infinity Interactive, Inc. - -L - -This library is free software; you can redistribute it and/or modify -it under the same terms as Perl itself. +Moose provides an attribute option called C. This is called when +the attribute's value is being set in the constructor, and lets you change the +value before it is set. =cut