X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FMoose%2FManual%2FAttributes.pod;h=5ff0bb1c17ebc8289016e5296b5f093ae01a4eec;hb=66c87ce3bdc0e6caec3058561d278a7221d69f72;hp=8ed02580d3587d5a72e8009daacfa2bb21dd2ab2;hpb=237e5f6069459296c54500897c69299e0b4377a5;p=gitmo%2FMoose.git diff --git a/lib/Moose/Manual/Attributes.pod b/lib/Moose/Manual/Attributes.pod index 8ed0258..5ff0bb1 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 @@ -36,16 +38,21 @@ Use the C function to declare an attribute: This says that all C objects have an optional read-write "first_name" attribute. -=head2 Read-write Vs read-only +=head2 Read-write vs. read-only -The options passed to C define the properties of the -attribute. There are a 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 @@ -54,7 +61,7 @@ read and write the value of that attribute for an object. By default, the accessor method has the same name as the attribute. If you declared your attribute as C then your accessor will be -read-only. If you declared it read-write, you get a read-write +read-only. If you declared it as C, you get a read-write accessor. Simple. Given our C example above, we now have a single C @@ -67,12 +74,12 @@ particularly handy when you'd like an attribute to be publicly readable, but only privately settable. For example: has 'weight' => ( - is => 'rw', + is => 'ro', writer => '_set_weight', ); -This might be useful if weight is calculated based on other methods, -for example every time the C method is called, we might adjust +This might be useful if weight is calculated based on other methods. +For example, every time the C method is called, we might adjust weight. This lets us hide the implementation details of weight changes, but still provide the weight value to users of the class. @@ -91,7 +98,7 @@ C methods: If you're thinking that doing this over and over would be insanely tedious, you're right! Fortunately, Moose provides a powerful -extension system that lets override the default naming +extension system that lets you override the default naming conventions. See L for more details. =head2 Predicate and clearer methods @@ -102,8 +109,9 @@ you want to access this information, you must define clearer and predicate methods for an attribute. A predicate method tells you whether or not a given attribute is -currently set. Note an attribute can be explicitly set to C or -some other false value, but the predicate will return true. +currently set. Note that an attribute can be explicitly set to +C or some other false value, but the predicate will return +true. The clearer method unsets the attribute. This is I the same as setting the value to C, but you can only distinguish @@ -142,8 +150,9 @@ predicate, and clearer method. my $person2 = Person->new( ssn => '111-22-3333'); $person2->has_ssn; # true -By default, Moose does not make a predicate or clearer for you. You -must explicitly provide names for them. +By default, Moose does not make a predicate or clearer for you. You must +explicitly provide names for them, and then Moose will create the methods +for you. =head2 Required or not? @@ -159,9 +168,9 @@ required, simply set the C option to true: There are a couple caveats worth mentioning in regards to what "required" actually means. -Basically, all it says is that this attribute (C) must be provided -to the constructor. It does not say anything about its value, so it -could be C. +Basically, all it says is that this attribute (C) must be provided to +the constructor, or be lazy with either a default or a builder. It does not +say anything about its value, so it could be C. If you define a clearer method on a required attribute, the clearer I work, so even a required attribute can be unset after object @@ -203,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'; }, ); @@ -224,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', @@ -238,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', @@ -260,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. @@ -285,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 @@ -311,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: @@ -340,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 @@ -399,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', @@ -413,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 @@ -437,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 @@ -448,23 +416,32 @@ set: ); sub _size_set { - my ( $self, $size, $meta_attr ) = @_; + 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 well -as the L object for the attribute. 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 after method modifier in two ways. First, a +This differs from an C method modifier in two ways. First, a trigger is only called when the attribute is set, as opposed to whenever the accessor method is called (for reading or -writing). Second, it is also called if the when an attribute's value -is passed to the constructor. +writing). Second, it is also called when an attribute's value is +passed to the constructor. However, triggers are I called when an attribute is populated -from a C or C +from a C or C. =head2 Attribute types @@ -490,7 +467,7 @@ discussion of Moose's type system. =head2 Delegation -Attributes can define methods which simply delegate to their values: +An attribute can define methods which simply delegate to its value: has 'hair_color' => ( is => 'ro', @@ -505,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; @@ -545,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<+>): @@ -597,12 +559,30 @@ 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 -aspects of their aspects. We recommend that you read the -L and L documents to -get a more complete understanding of attribute features. +aspects. We recommend that you read the L +and L documents to get a more complete +understanding of attribute features. =head1 A FEW MORE OPTIONS @@ -633,30 +613,15 @@ 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 -they are accessed and manipulated. +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. See also +L. =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