Checking in the first chunk of the Attributes manual section
Dave Rolsky [Fri, 12 Dec 2008 21:19:02 +0000 (21:19 +0000)]
lib/Moose/Manual/Attributes.pod [new file with mode: 0644]

diff --git a/lib/Moose/Manual/Attributes.pod b/lib/Moose/Manual/Attributes.pod
new file mode 100644 (file)
index 0000000..58cd3c6
--- /dev/null
@@ -0,0 +1,323 @@
+=pod
+
+=head1 NAME
+
+Moose::Manual::Attribute - Object attributes with Moose
+
+=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.
+
+Attributes are properties 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
+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.
+
+=head1 ATTRIBUTE 101
+
+Use the C<has> function to declare an attribute:
+
+  package Person;
+
+  use Moose;
+
+  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.
+
+=head2 Read-write Vs Read-only
+
+The code inside the parentheses defines 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).
+
+(In fact, you could even omit C<is>, but that leaves you with an
+attribute that has no accessors, which is pointless unless you're
+doing some deep, dark magic).
+
+=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.
+
+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.
+
+If you want, you can also explicitly specify the method names to be
+used for getting and setting an attribute's value. This is
+particularly handy when you'd like an attribute to be publically
+readable, but only privately settable. For example:
+
+  has 'weight' =>
+      ( is     => 'rw',
+        writer => '_set_weight',
+      );
+
+This might be useful if weight is calculated based on other methods,
+for example every time the C<eat> 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.
+
+Some people might prefer to have distinct methods for getting and
+setting, even when setting is a public method. In I<Perl Best
+Practices>, Damian Conway recommends that getter methods start with
+"get_" and setter methods start with "set_".
+
+We can do exactly that by providing names for both the C<reader> and
+C<writer> methods:
+
+  has 'weight' =>
+      ( is     => 'rw',
+        reader => 'get_weight',
+        writer => 'set_weight',
+      );
+
+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 you do things like override the default
+accessor method conventions. See L<Moose::Manual::MooseX> for more
+details.
+
+=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.
+
+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.
+
+The clearer method unsets the attribute. This is I<not> the
+same as setting the value to C<undef>, but you can only distinguish
+between them if you define a predicate method!
+
+Here's some code to illustrate the relationship between an accessor,
+predicate, and clearer method.
+
+  package Person;
+
+  use Moose;
+
+  has 'ssn' =>
+      ( is        => 'rw',
+        clearer   => 'clear_ssn',
+        predicate => 'has_ssn',
+      );
+
+  ...
+
+  my $person = Person->new();
+  $person->has_ssn; # false
+
+  $person->ssn(undef);
+  $person->ssn; # returns undef
+  $person->has_ssn; # true
+
+  $person->clear_ssn;
+  $person->ssn; # returns undef
+  $person->has_ssn; # false
+
+  $person->ssn('123-45-6789');
+  $person->ssn; # returns '123-45-6789'
+  $person->has_ssn; # true
+
+  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.
+
+=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 required option to true:
+
+  has 'name' =>
+      ( is       => 'rw',
+        required => 1,
+      );
+
+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>.
+
+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.
+
+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> clearer and predicate for a required
+attribute.
+
+=head2 Default and Builder Methods
+
+Attributes can have default values, and there are several ways to
+specify this.
+
+In the simplest form, you simply provide a non-reference scalar value
+for the "default" option:
+
+  has 'size' =>
+      ( is        => 'rw',
+        default   => 'medium',
+        predicate => 'has_size',
+      );
+
+If the size attribute is not provided to the constructor, then it ends
+up being set to "medium":
+
+  my $person = Person->new();
+  $person->size; # medium
+  $person->has_size; # true
+
+You can also provide a subroutine reference for default. This
+reference will be called a method on the object.
+
+  has 'size' =>
+      ( is        => 'rw',
+        default   =>
+            sub { ('small', 'medium', 'large')[ int( rand 3 ) ] },
+        predicate => 'has_size',
+      );
+
+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 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
+Perl would instantiate the reference exactly once, and it would be
+shared by all objects:
+
+  has 'mapping' =>
+      ( is      => 'rw',
+        default => {}, # wrong!
+      );
+
+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      => 'rw',
+        default => sub { {} }, # right!
+      );
+
+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 builder method for your attribute:
+
+  has 'size' =>
+      ( is        => 'rw',
+        builder   => '_build_size',
+        predicate => 'has_size',
+      );
+
+  sub _build_size {
+      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. Second, the C<_build_size> method can be overridden in
+subclasses.
+
+We strongly recommend that you use a builder instead of a default for
+anything beyond the most trivial default.
+
+=head2 Laziness and lazy_build
+
+Moose lets you defer attribute population by making an attribute lazy:
+
+  has 'size' =>
+      ( is        => 'rw',
+        lazy      => 1,
+        builder   => '_build_size',
+      );
+
+When the 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.
+
+First, if the default value for this attribute depends on some other
+attributes, then the attribute I<must> be 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.
+
+Second, there's often no reason to spend program time calculating a
+default before its needed. Making an attribute 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 lazy as a matter of course.
+
+To facilitate this, you can simply specify the C<lazy_build> attribute
+option. This bundles up a number of options together:
+
+  has 'size' =>
+      ( is         => 'rw',
+        lazy_build => 1,
+      );
+
+This is the same as specifying all of these options:
+
+  has 'size' =>
+      ( is        => 'rw',
+        lazy      => 1,
+        builder   => '_build_size',
+        clearer   => 'clear_size',
+        predicate => 'has_size',
+      );
+
+If your attribute name starts with an underscore (_), then the clearer
+and predicate will as well:
+
+  has '_size' =>
+      ( is         => 'rw',
+        lazy_build => 1,
+      );
+
+becomes ...
+
+  has '_size' =>
+      ( is        => 'rw',
+        lazy      => 1,
+        builder   => '_build__size',
+        clearer   => '_clear_size',
+        predicate => '_has_size',
+      );
+
+Note the doubled underscore in the builder name. The lazy_build simply
+prepends the attribute name with "_build_" to come up with the builder
+name.
+
+=head2 Private Attributes