[Moose-commits] r7116 - Moose/branches/moose-manual/lib/Moose/Manual
autarch at code2.0beta.co.uk
autarch at code2.0beta.co.uk
Tue Dec 16 20:50:48 GMT 2008
Author: autarch
Date: 2008-12-16 12:50:46 -0800 (Tue, 16 Dec 2008)
New Revision: 7116
Modified:
Moose/branches/moose-manual/lib/Moose/Manual/Attributes.pod
Log:
Lots of cleanup in the text.
Add init_arg section.
Add boilerplate
Modified: Moose/branches/moose-manual/lib/Moose/Manual/Attributes.pod
===================================================================
--- Moose/branches/moose-manual/lib/Moose/Manual/Attributes.pod 2008-12-16 20:35:08 UTC (rev 7115)
+++ Moose/branches/moose-manual/lib/Moose/Manual/Attributes.pod 2008-12-16 20:50:46 UTC (rev 7116)
@@ -6,18 +6,19 @@
=head1 INTRODUCTION
-Attributes are the most feature-rich part of Moose, and also one of
-the most useful. It's easy to imagine a class without roles or method
-modifiers, but almost every class has attributes.
+Moose has many attribute-related features, and attributes are probably
+the single most useful aspect of Moose. You can do a lot in a class
+just by declaring attributes. In fact, it's quite possible to have
+classes that consist solely of attribute declarations.
-Attributes are properties that every member of a class has. For
+An Attribute is a property that every member of a class has. For
example, we might say that "every Person object has a first name and
-last name. Attributes can be optional, so that we can say "some Person
+last name". Attributes can be optional, so that we can say "some Person
objects have a social security number (and some don't)".
-At its simplest, an attribute can be thought of slot in hash that can
-be read and set. However, attributes, can also have things like
-default values, laziness, type constraints, delegation and much more.
+At its simplest, an attribute can be thought of as a named value (as
+in a hash) that can be read and set. However, attributes can also have
+defaults, type constraints, delegation and much more.
=head1 ATTRIBUTE OPTIONS
@@ -29,12 +30,12 @@
has 'first_name' => ( is => 'rw' );
-This says that all person objects have an optional "first_name"
-attribute that can be both read and set on the object.
+This says that all person objects have an optional read-write
+"first_name" attribute.
=head2 Read-write Vs Read-only
-The code inside the parentheses defines the details of the
+The options passed to C<has> define the details of the
attribute. There are a lot of options you can put here, but in the
simplest form you just need to include C<is>, which can be either
C<rw> (read-write) or C<ro> (read-only).
@@ -46,15 +47,15 @@
=head2 Accessor Methods
Each attribute has one or more accessor methods. An accessor lets you
-read and write the value of the attribute for an object.
+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<ro> then your accessor will be
read-only. If you declared it read-write, you get a read-write
accessor. Simple.
-So with our Person example above, we now have a single C<first_name>
-accessor that can set or return a person object's first name.
+Given our Person example above, we now have a single C<first_name>
+accessor that can read or write a person object's first name.
If you want, you can also explicitly specify the method names to be
used for reading and writing an attribute's value. This is
@@ -72,9 +73,8 @@
changes, but still provide the weight value to users of the class.
Some people might prefer to have distinct methods for reading and
-writing, even when writing is a public method. In I<Perl Best
-Practices>, Damian Conway recommends that reader methods start with
-"get_" and writer methods start with "set_".
+writing. In I<Perl Best Practices>, Damian Conway recommends that
+reader methods start with "get_" and writer methods start with "set_".
We can do exactly that by providing names for both the C<reader> and
C<writer> methods:
@@ -93,15 +93,14 @@
=head2 Predicate and Clearer Methods
-Moose is able to explicitly distinguish between false or undefined
-values, and an attribute which is not set. If you want to be able to
-access and manipulate these states, you also need to define clearer
-and predicate methods for your attributes.
+Moose allows you to explicitly distinguish between a false or
+undefined attribute value and an attribute which is not set. If you
+want to be able access this information, you must define clearer and
+predicate methods for an attribute.
-A predicate method can be used to determine whether or not a given
-attribute is currently set. Note that even if the attribute was
-explicitly set to undef or some other false value, the predicate will
-return true.
+A predicate method tells you whether or not a given attribute is
+currently set. Note that even if the attribute was explicitly set to
+undef or some other false value, the predicate will return true.
The clearer method unsets the attribute. This is I<not> the
same as setting the value to C<undef>, but you can only distinguish
@@ -140,15 +139,15 @@
my $person2 = Person->new( ssn => '111-22-3333');
$person2->has_ssn; # true
-Note that by default, Moose does not make a predicate or clearer for
-you. You have to explicitly provide a method name for the ones you
-want.
+By default, Moose does not make a predicate or clearer for you. You
+must explicitly provide method names for these options if you want
+them.
=head2 Required or Not?
-By default, all attributes are optional. That means that they do not
-need to be provided at object construction time. If you want to make
-an attribute required, simply set the C<required> option to true:
+By default, all attributes are optional, and do not need to be
+provided at object construction time. If you want to make an attribute
+required, simply set the C<required> option to true:
has 'name' =>
( is => 'rw',
@@ -158,23 +157,23 @@
There are a couple caveats worth mentioning in regards to what
required actually means.
-Basically, all it says is that this attribute must be provided to the
-constructor. It does not say anything about its value, so it could be
-C<undef>.
+Basically, all it says is that this attribute (name) must be provided
+to the constructor. It does not say anything about its value, so it
+could be C<undef>.
If you define a clearer method on a required attribute, the clearer
-I<will> work. So even though something is defined as required, you can
-remove it after object construction.
+I<will> work, so even a required attribute can be unset after object
+construction.
-So if you do make an attribute required, that probably means that
-providing a clearer doesn't make much sense. In some cases, it might
-be handy to have a I<private> C<clearer> and C<predicate> for a
-required attribute.
+This means that if you do make an attribute required, providing a
+clearer doesn't make much sense. In some cases, it might be handy to
+have a I<private> C<clearer> and C<predicate> for a required
+attribute.
=head2 Default and Builder Methods
-Attributes can have default values, and there are several ways to
-specify this.
+Attributes can have default values, and Moose provides two ways to
+specify that default.
In the simplest form, you simply provide a non-reference scalar value
for the C<default> option:
@@ -205,10 +204,10 @@
This is dumb example, but it illustrates the point that the subroutine
will be called for every new object created.
-Of course, if it's called during object construction, it may be before
-other attributes have been set. If your default is dependent on other
-parts of the object's state, you can make the default c<lazy>, which
-is covered in the next section.
+Of course, if it's called during object construction, it may be called
+before other attributes have been set. If your default is dependent on
+other parts of the object's state, you can make the default c<lazy>,
+which 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
@@ -220,6 +219,9 @@
default => {}, # wrong!
);
+Moose will throw an error if you pass a bare non-subroutine reference
+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:
@@ -263,20 +265,20 @@
builder => '_build_size',
);
-When the C<lazy> option is true, the attribute is not populated until
-the reader method is called, rather than at object construction
-time. There are several reasons you might choose to do this.
+When C<lazy> is true, the attribute is not populated until the reader
+method is called, rather than at object construction time. There are
+several reasons you might choose to do this.
First, if the default value for this attribute depends on some other
attributes, then the attribute I<must> be C<lazy>. During object
-construction, default subroutine references are not called in any
-particular order, so you cannot count on other attribute being
-populated at that time.
+construction, defaults are not generated in a predictable order, so
+you cannot count on some other attribute being populated in a non-lazy
+default subroutine.
-Second, there's often no reason to spend program time calculating a
-default before its needed. Making an attribute C<lazy> lets you defer
-the cost until the attribute is needed. If the attribute is I<never>
-needed, you save some CPU time.
+Second, there's often no reason to calculate a default before it's
+needed. Making an attribute C<lazy> lets you defer the cost until the
+attribute is needed. If the attribute is I<never> needed, you save
+some CPU time.
We recommend that you make any attribute with a builder or non-trivial
default C<lazy> as a matter of course.
@@ -327,16 +329,45 @@
has 'size' =>
( is => 'rw',
lazy_build => 1,
- clearer => '_has_size',
+ clearer => '_clear_size',
);
Options that you explicitly provide are always used in favor of
Moose's internal defaults.
+=head2 Constructor Parameters (init_arg)
+
+By default, each attribute can be passed by name to the class's
+constructor. On occassion, you may want to use a different name for
+the constructor parameter. You may also want to make an attribute
+unsettable from the constructor.
+
+Both of these things can be done by providing a value for the
+C<init_arg> option:
+
+ has 'bigness' =>
+ ( is => 'rw',
+ init_arg => 'size',
+ );
+
+Now we have an attribute named bigness, but to set it during object
+construction we pass C<size> to the constructor.
+
+Even more useful is the ability to disable setting attribute. This is
+particularly handy for private attributes:
+
+ has '_genetic_code' =>
+ ( is => 'rw',
+ init_arg => undef,
+ );
+
+By setting the C<init_arg> to C<undef>, we make it impossible to set
+this attribute when creating a new object.
+
=head2 Weak References
Moose has built-in support for weak references. If you set the
-C<weak_ref> to a true value for the attribute, then it will call
+C<weak_ref> option to a true value, then it will call
C<Scalar::Util::weaken> whenever the attribute is set:
has 'parent' =>
@@ -351,8 +382,8 @@
=head2 Triggers
-You can provide a C<trigger> option as a subroutine reference which
-will be called whenever the attribute is set:
+A C<trigger> is a subroutine that is called whenever the attribute is
+set:
has 'size' =>
( is => 'rw',
@@ -362,15 +393,16 @@
sub _size_set {
my ( $self, $size, $meta_attr ) = @_;
- print $self->name, " size is now $size\n";
+ warn $self->name, " size is now $size\n";
}
The trigger is called as a method, and receives the new value as well
-as the L<Moose::Meta::Attribute> object for the attribute.
+as the L<Moose::Meta::Attribute> object for the attribute. The trigger
+is called I<after> the value is set.
=head2 Attribute Types
-Attributes can be restriced to only accept certain types:
+Attributes can be restricted to only accept certain types:
has 'first_name' =>
( is => 'rw',
@@ -392,7 +424,7 @@
=head2 Delegation
-Attributes can define delegations to their values:
+Attributes can define methods which simple delegate to their values:
has 'hair_color' =>
( is => 'rw',
@@ -400,8 +432,9 @@
handles => { hair_color_hex => 'as_hex_string' },
);
-This adds a new method, C<hair_color_hex>. Internally, this just calls
-C<< $self->hair_color->as_hex_string >>.
+This adds a new method, C<hair_color_hex>. When someone calls
+C<hair_color_hex>, internally, the object just calls C<<
+$self->hair_color->as_hex_string >>.
See L<Moose::Manual::Delegation> for more details on how to set up
delegation methods.
@@ -409,7 +442,7 @@
=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 new metaclasses and metaclass traits.
+of ways through the use of custom metaclasses and metaclass traits.
When declaring an attribute, you can declare a metaclass or a set of
traits for the attribute:
@@ -427,7 +460,6 @@
You can also apply one or more traits to an attribute:
-
use MooseX::MetaDescription;
has 'size' =>
@@ -449,8 +481,8 @@
=head2 Attribute Inheritance
By default, a child inherits all of its parent class(es)' attributes
-as-is. You can explicitly change some aspects of the inherited
-attribute in the child class.
+as-is. However, you can explicitly change some aspects of the
+inherited attribute in the child class.
The options that can be overridden in a subclass are:
@@ -547,3 +579,18 @@
topics. We recommend that you read the L<Moose::Manual::Delegation>
and L<Moose::Manual::Types> documents to get a more complete
understanding of attribute features.
+
+=head1 AUTHOR
+
+Dave Rolsky E<lt>autarch at urth.orgE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 2008 by Infinity Interactive, Inc.
+
+L<http://www.iinteractive.com>
+
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.
+
+=cut
More information about the Moose-commits
mailing list