has 'balance' => (isa => 'Int', is => 'rw', default => 0);
-This tells is that a B<BankAccount> has a C<balance> attribute,
-which is has the C<Int> type constraint, a read/write accessor,
+This tells us that a B<BankAccount> has a C<balance> attribute,
+which has the C<Int> type constraint, a read/write accessor,
and a default value of C<0>. This means that every instance of
-B<BankAccount> that is created will have it's C<balance> slot
+B<BankAccount> that is created will have its C<balance> slot
initialized to C<0>. Very simple really :)
Next come the methods. The C<deposit> and C<withdraw> methods
that class. This means that in the first recipe, a C<Point> and
C<Point3D> type constraint were created, and in this recipe, both
a C<BankAccount> and a C<CheckingAccount> type constraint were
-created. Moose does this as a convience for you so that your
+created. Moose does this as a convenience for you so that your
class model and the type constraint model can both be kept in
sync with one another. In short, Moose makes sure that it will
just DWIM (1).
to call C<SUPER::withdraw> and to pass it the C<$amount> argument.
Instead the method modifier assures that all arguments make it
to the superclass method correctly. But this is actually more
-than just a convience for forgetful programmers, it also helps
+than just a convenience for forgetful programmers, it also helps
isolate subclasses from changes in the superclasses. For instance,
if B<BankAccount::withdraw> were to add an additional argument
of some kind, the version of B<CheckingAccount::withdraw> which
uses C<SUPER::withdraw> would not pass that extra argument
-correctly. Whereas the method modifier version of would pass
-all arguments along correctly automatically.
+correctly. Whereas the method modifier version would automatically pass
+along all arguments correctly.
Just as with the first recipe, object instantiation is a fairly
normal process, here is an example:
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
-=cut
\ No newline at end of file
+=cut
slot to hold the right node, a C<left> slot to hold the left node,
and finally a C<parent> slot to hold a reference back up the tree.
-Now, lets start with the code, our first attribute is the C<node>
+Now, let's start with the code, our first attribute is the C<node>
slot, defined as such:
has 'node' => (is => 'rw', isa => 'Any');
The new item here is the type constraint of C<Any>. In the type
constraint heirarchy in L<Moose::Utils::TypeConstraints>, the C<Any>
constraint is the "root" of the hierarchy. It means exactly what it
-says, it allows anything to pass. Now, you could just as easily of left
-the C<isa> out, and left the C<node> slot unconstrainted and gotten the
-same behavior. But here, we are really including the type costraint
+says, it allows anything to pass. Now, you could just as easily have
+left out the C<isa>, left the C<node> slot unconstrained and gotten the
+same behavior. But here, we are really including the type constraint
for the benefit of other programmers, not the computer. It makes
clear my intent that the C<node> can be of any type, and that the
class is a polymorphic container. Next, lets move onto the C<parent>
-slot.
+slot.
has 'parent' => (
is => 'rw',
);
As you already know from reading the previous recipes, this code
-tells you that C<parent> gets a read/write accessor, is constrainted
+tells you that C<parent> gets a read/write accessor and is constrained
to only accept instances of B<BinaryTree>. You will of course remember
from the second recipe that the C<BinaryTree> type constraint is
automatically created for us by Moose.
default => sub { BinaryTree->new(parent => $_[0]) },
);
-You already know what the C<is>, C<isa> and C<>predicate> options
+You already know what the C<is>, C<isa> and C<predicate> options
do, but now we have two more new options. These two options are
actually linked together, in fact, you cannot use the C<lazy>
option unless you have set the C<default> option. The class
be stored. This added feature can come in quite handy at times, as
is illustrated above, with this code:
- default => sub { BinaryTree->new(parent => $_[0]) },
-
+ default => sub { BinaryTree->new(parent => $_[0]) },
+
The default value being generated is a new C<BinaryTree> instance
for the C<left> (or C<right>) slot. Here we set up the parental
relationship by passing the current instance to the constructor.
sooner), the slot will be populated with the value of the C<default>
option.
-This option is what allows the B<BinaryTree> class to instantiate
-objects without fear of the I<infinitely recursive spiral of death>
-I mentioned earlier.
+This option is what allows the B<BinaryTree> class to instantiate
+objects without fear of the I<infinitely recursive spiral of death>
+mentioned earlier.
-So, we have descibed a quite complex set of behaviors here, and not
-one method has needed to be written. But wait, we can't get away that
+So, we have described a quite complex set of behaviors here, and not
+one method had to be written. But wait, we can't get away that
easily. The autogenerated C<right> and C<left> accessors are not
completely correct. They will not install the parental relationships
that we need. We could write our own accessors, but that would require
opened your mind to the powerful possibilities of Moose. In the next
recipe we explore how we can create custom subtypes and take
advantage of the plethora of useful modules out on CPAN with Moose.
-
+
=head1 FOOTNOTES
=over 4
without having to build an entire class to represent them. We
will also show how this feature can be used to leverage the
usefulness of CPAN modules. In addition to this, we will also
-introduce another attribute option as well.
+introduce another attribute option.
-Lets first get into the C<subtype> features. In the B<Address>
+Let's first get into the C<subtype> features. In the B<Address>
class we have defined two subtypes. The first C<subtype> uses
the L<Locale::US> module, which provides two hashes which can be
used to do existence checks for state names and their two letter
duplication) because type constraints are stored by string in a
global registry and always accessible to C<has>.
-With these two subtypes and some attributes, we pretty much define
+With these two subtypes and some attributes, we have defined
as much as we need for a basic B<Address> class. Next we define
a basic B<Company> class, which itself has an address. As we saw in
earlier recipes, we can use the C<Address> type constraint that
accept an undefined value for the slot. The result is that C<name>
should always have a value.
-The next attribute option is not actually a new one, but a new varient
+The next attribute option is not actually new, but a new variant
of options we have already introduced.
has 'employees' => (is => 'rw', isa => subtype ArrayRef => where {
(blessed($_) && $_->isa('Employee') || return) for @$_; 1
});
-
+
Here, instead of passing a string to the C<isa> option, we are passing
an anyonomous subtype of the C<ArrayRef> type constraint. This subtype
basically checks that all the values in the ARRAY ref are instance of
The next place we need to address is the C<employees> read/write
accessor (see the C<employees> attribute declaration above). This
accessor will properly check the type constraint, but we need to add
-so additional behavior. For this we use an C<after> method modifier
+some additional behavior. For this we use an C<after> method modifier
like so:
after 'employees' => sub {
C<$employees> argument.
At this point, our B<Company> class is complete. Next comes our B<Person>
-class and it's subclass the previously mentioned B<Employee> class.
+class and its subclass the previously mentioned B<Employee> class.
The B<Person> class should be obvious to you at this point. It has a few
C<required> attributes, and the C<middle_intial> slot has an additional
B<Company> instance. The only new item, which we have seen before in
examples, but never in the recipe itself, is the C<override> method
modifier.
-
+
override 'full_name' => sub {
my $self = shift;
super() . ', ' . $self->title
};
-This just tells Moose that I am intetionally overriding the superclass
+This just tells Moose that I am intentionally overriding the superclass
C<full_name> method here, and adding the value of the C<title> slot at
the end of the employee's full name.
-And thats about it.
+And that's about it.
Once again, as with all the other recipes, you can go about using
these classes like any other Perl 5 class. A more detailed example of
been (including all the type constraint checks, weak references, etc).
And of course, this recipe also introduced the C<subtype> keyword, and
-it's usefulness within the Moose toolkit. In the next recipe we will
+its usefulness within the Moose toolkit. In the next recipe we will
focus more on subtypes, and introduce the idea of type coercion as well.
-
+
=head1 FOOTNOTES
=over 4
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
-=cut
\ No newline at end of file
+=cut