=begin testing-SETUP
-BEGIN {
- eval 'use Regexp::Common; use Locale::US;';
- if ($@) {
- diag 'Regexp::Common & Locale::US required for this test';
- ok(1);
- exit 0;
- }
-}
+use Test::Requires {
+ 'Locale::US' => '0',
+ 'Regexp::Common' => '0',
+};
=end testing-SETUP
sub BUILD {
my ( $self, $params ) = @_;
- if ( @{ $self->employees || [] } ) {
- foreach my $employee ( @{ $self->employees } ) {
- $employee->employer($self);
- }
+ foreach my $employee ( @{ $self->employees || [] } ) {
+ $employee->employer($self);
}
}
after 'employees' => sub {
my ( $self, $employees ) = @_;
- if ($employees) {
- foreach my $employee ( @{$employees} ) {
- $employee->employer($self);
- }
+ foreach my $employee ( @{ $employees || [] } ) {
+ $employee->employer($self);
}
};
class.
In the recipe we also make use of L<Locale::US> and L<Regexp::Common>
-to build constraints, showing how how constraints can make use of
-existing CPAN tools for data validation.
+to build constraints, showing how constraints can make use of existing
+CPAN tools for data validation.
Finally, we introduce the C<required> attribute option.
-The the C<Address> class we define two subtypes. The first uses the
+In the C<Address> class we define two subtypes. The first uses the
L<Locale::US> module to check the validity of a state. It accepts
either a state abbreviation of full name.
noting that an I<empty> array reference also satisfies this
constraint.
-Parameterizable type constraints (or "container types), such as
+Parameterizable type constraints (or "container types"), such as
C<ArrayRef[`a]>, can be made more specific with a type parameter. In
fact, we can arbitrarily nest these types, producing something like
C<HashRef[ArrayRef[Int]]>. However, you can also just use the type by
sub BUILD {
my ( $self, $params ) = @_;
- if ( $self->employees ) {
- foreach my $employee ( @{ $self->employees } ) {
- $employee->employer($self);
- }
+ foreach my $employee ( @{ $self->employees || [] } ) {
+ $employee->employer($self);
}
}
-The C<BUILD> method is executed after type constraints are checked, so
-it is safe to assume that C<< $self->employees >> will return an array
-reference, and that the elements of that array will be C<Employee>
-objects.
+The C<BUILD> method is executed after type constraints are checked, so it is
+safe to assume that if C<< $self->employees >> has a value, it will be an
+array reference, and that the elements of that array reference will be
+C<Employee> objects.
We also want to make sure that whenever the C<employees> attribute for
a C<Company> is changed, we also update the C<employer> for each
after 'employees' => sub {
my ( $self, $employees ) = @_;
- if ($employees) {
- foreach my $employee ( @{$employees} ) {
- $employee->employer($self);
- }
+ foreach my $employee ( @{ $employees || [] } ) {
+ $employee->employer($self);
}
};
-Again, as with the C<BUILD> method, we know that the type constraint
-check has already happened, so we can just check for definedness on the
-C<$employees> argument.
+Again, as with the C<BUILD> method, we know that the type constraint check has
+already happened, so we know that if C<$employees> is defined it will contain
+an array reference of C<Employee> objects..
-The B<Person> class does have demonstrate anything new. It has several
+The B<Person> class does not really demonstrate anything new. It has several
C<required> attributes. It also has a C<predicate> method, which we
first used in L<recipe 3|Moose::Cookbook::Basics::Recipe3>.
=head1 COPYRIGHT AND LICENSE
-Copyright 2006-2009 by Infinity Interactive, Inc.
+Copyright 2006-2010 by Infinity Interactive, Inc.
L<http://www.iinteractive.com>