Add built local::lib
[catagits/Gitalist.git] / local-lib5 / man / man3 / Moose::Cookbook::Basics::Recipe4.3pm
diff --git a/local-lib5/man/man3/Moose::Cookbook::Basics::Recipe4.3pm b/local-lib5/man/man3/Moose::Cookbook::Basics::Recipe4.3pm
new file mode 100644 (file)
index 0000000..4a02e0a
--- /dev/null
@@ -0,0 +1,467 @@
+.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.3
+.\"
+.\" Standard preamble:
+.\" ========================================================================
+.de Sh \" Subsection heading
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Vb \" Begin verbatim text
+.ft CW
+.nf
+.ne \\$1
+..
+.de Ve \" End verbatim text
+.ft R
+.fi
+..
+.\" Set up some character translations and predefined strings.  \*(-- will
+.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
+.\" double quote, and \*(R" will give a right double quote.  | will give a
+.\" real vertical bar.  \*(C+ will give a nicer C++.  Capital omega is used to
+.\" do unbreakable dashes and therefore won't be available.  \*(C` and \*(C'
+.\" expand to `' in nroff, nothing in troff, for use with C<>.
+.tr \(*W-|\(bv\*(Tr
+.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
+.ie n \{\
+.    ds -- \(*W-
+.    ds PI pi
+.    if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
+.    if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\"  diablo 12 pitch
+.    ds L" ""
+.    ds R" ""
+.    ds C` ""
+.    ds C' ""
+'br\}
+.el\{\
+.    ds -- \|\(em\|
+.    ds PI \(*p
+.    ds L" ``
+.    ds R" ''
+'br\}
+.\"
+.\" If the F register is turned on, we'll generate index entries on stderr for
+.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index
+.\" entries marked with X<> in POD.  Of course, you'll have to process the
+.\" output yourself in some meaningful fashion.
+.if \nF \{\
+.    de IX
+.    tm Index:\\$1\t\\n%\t"\\$2"
+..
+.    nr % 0
+.    rr F
+.\}
+.\"
+.\" For nroff, turn off justification.  Always turn off hyphenation; it makes
+.\" way too many mistakes in technical documents.
+.hy 0
+.if n .na
+.\"
+.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
+.\" Fear.  Run.  Save yourself.  No user-serviceable parts.
+.    \" fudge factors for nroff and troff
+.if n \{\
+.    ds #H 0
+.    ds #V .8m
+.    ds #F .3m
+.    ds #[ \f1
+.    ds #] \fP
+.\}
+.if t \{\
+.    ds #H ((1u-(\\\\n(.fu%2u))*.13m)
+.    ds #V .6m
+.    ds #F 0
+.    ds #[ \&
+.    ds #] \&
+.\}
+.    \" simple accents for nroff and troff
+.if n \{\
+.    ds ' \&
+.    ds ` \&
+.    ds ^ \&
+.    ds , \&
+.    ds ~ ~
+.    ds /
+.\}
+.if t \{\
+.    ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
+.    ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
+.    ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
+.    ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
+.    ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
+.    ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
+.\}
+.    \" troff and (daisy-wheel) nroff accents
+.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
+.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
+.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
+.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
+.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
+.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
+.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
+.ds ae a\h'-(\w'a'u*4/10)'e
+.ds Ae A\h'-(\w'A'u*4/10)'E
+.    \" corrections for vroff
+.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
+.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
+.    \" for low resolution devices (crt and lpr)
+.if \n(.H>23 .if \n(.V>19 \
+\{\
+.    ds : e
+.    ds 8 ss
+.    ds o a
+.    ds d- d\h'-1'\(ga
+.    ds D- D\h'-1'\(hy
+.    ds th \o'bp'
+.    ds Th \o'LP'
+.    ds ae ae
+.    ds Ae AE
+.\}
+.rm #[ #] #H #V #F C
+.\" ========================================================================
+.\"
+.IX Title "Moose::Cookbook::Basics::Recipe4 3"
+.TH Moose::Cookbook::Basics::Recipe4 3 "2009-05-05" "perl v5.8.7" "User Contributed Perl Documentation"
+.SH "NAME"
+Moose::Cookbook::Basics::Recipe4 \- Subtypes, and modeling a simple \fBCompany\fR class hierarchy
+.SH "SYNOPSIS"
+.IX Header "SYNOPSIS"
+.Vb 3
+\&  package Address;
+\&  use Moose;
+\&  use Moose::Util::TypeConstraints;
+.Ve
+.PP
+.Vb 2
+\&  use Locale::US;
+\&  use Regexp::Common 'zip';
+.Ve
+.PP
+.Vb 7
+\&  my $STATES = Locale::US\->new;
+\&  subtype 'USState'
+\&      => as Str
+\&      => where {
+\&             (    exists $STATES\->{code2state}{ uc($_) }
+\&               || exists $STATES\->{state2code}{ uc($_) } );
+\&         };
+.Ve
+.PP
+.Vb 5
+\&  subtype 'USZipCode'
+\&      => as Value
+\&      => where {
+\&             /^$RE{zip}{US}{\-extended => 'allow'}$/;
+\&         };
+.Ve
+.PP
+.Vb 4
+\&  has 'street'   => ( is => 'rw', isa => 'Str' );
+\&  has 'city'     => ( is => 'rw', isa => 'Str' );
+\&  has 'state'    => ( is => 'rw', isa => 'USState' );
+\&  has 'zip_code' => ( is => 'rw', isa => 'USZipCode' );
+.Ve
+.PP
+.Vb 3
+\&  package Company;
+\&  use Moose;
+\&  use Moose::Util::TypeConstraints;
+.Ve
+.PP
+.Vb 3
+\&  has 'name' => ( is => 'rw', isa => 'Str', required => 1 );
+\&  has 'address'   => ( is => 'rw', isa => 'Address' );
+\&  has 'employees' => ( is => 'rw', isa => 'ArrayRef[Employee]' );
+.Ve
+.PP
+.Vb 8
+\&  sub BUILD {
+\&      my ( $self, $params ) = @_;
+\&      if ( @{ $self\->employees || [] } ) {
+\&          foreach my $employee ( @{ $self\->employees } ) {
+\&              $employee\->employer($self);
+\&          }
+\&      }
+\&  }
+.Ve
+.PP
+.Vb 8
+\&  after 'employees' => sub {
+\&      my ( $self, $employees ) = @_;
+\&      if ($employees) {
+\&          foreach my $employee ( @{$employees} ) {
+\&              $employee\->employer($self);
+\&          }
+\&      }
+\&  };
+.Ve
+.PP
+.Vb 2
+\&  package Person;
+\&  use Moose;
+.Ve
+.PP
+.Vb 7
+\&  has 'first_name' => ( is => 'rw', isa => 'Str', required => 1 );
+\&  has 'last_name'  => ( is => 'rw', isa => 'Str', required => 1 );
+\&  has 'middle_initial' => (
+\&      is        => 'rw', isa => 'Str',
+\&      predicate => 'has_middle_initial'
+\&  );
+\&  has 'address' => ( is => 'rw', isa => 'Address' );
+.Ve
+.PP
+.Vb 9
+\&  sub full_name {
+\&      my $self = shift;
+\&      return $self\->first_name
+\&          . (
+\&          $self\->has_middle_initial
+\&          ? ' ' . $self\->middle_initial . '. '
+\&          : ' '
+\&          ) . $self\->last_name;
+\&  }
+.Ve
+.PP
+.Vb 2
+\&  package Employee;
+\&  use Moose;
+.Ve
+.PP
+.Vb 1
+\&  extends 'Person';
+.Ve
+.PP
+.Vb 2
+\&  has 'title'    => ( is => 'rw', isa => 'Str',     required => 1 );
+\&  has 'employer' => ( is => 'rw', isa => 'Company', weak_ref => 1 );
+.Ve
+.PP
+.Vb 4
+\&  override 'full_name' => sub {
+\&      my $self = shift;
+\&      super() . ', ' . $self\->title;
+\&  };
+.Ve
+.SH "DESCRIPTION"
+.IX Header "DESCRIPTION"
+This recipe introduces the \f(CW\*(C`subtype\*(C'\fR sugar function from
+Moose::Util::TypeConstraints. The \f(CW\*(C`subtype\*(C'\fR function lets you
+declaratively create type constraints without building an entire
+class.
+.PP
+In the recipe we also make use of Locale::US and Regexp::Common
+to build constraints, showing how constraints can make use of existing
+\&\s-1CPAN\s0 tools for data validation.
+.PP
+Finally, we introduce the \f(CW\*(C`required\*(C'\fR attribute option.
+.PP
+The the \f(CW\*(C`Address\*(C'\fR class we define two subtypes. The first uses the
+Locale::US module to check the validity of a state. It accepts
+either a state abbreviation of full name.
+.PP
+A state will be passed in as a string, so we make our \f(CW\*(C`USState\*(C'\fR type
+a subtype of Moose's builtin \f(CW\*(C`Str\*(C'\fR type. This is done using the \f(CW\*(C`as\*(C'\fR
+sugar. The actual constraint is defined using \f(CW\*(C`where\*(C'\fR. This function
+accepts a single subroutine reference. That subroutine will be called
+with the value to be checked in \f(CW$_\fR (1). It is expected to return a
+true or false value indicating whether the value is valid for the
+type.
+.PP
+We can now use the \f(CW\*(C`USState\*(C'\fR type just like Moose's builtin types:
+.PP
+.Vb 1
+\&  has 'state'    => ( is => 'rw', isa => 'USState' );
+.Ve
+.PP
+When the \f(CW\*(C`state\*(C'\fR attribute is set, the value is checked against the
+\&\f(CW\*(C`USState\*(C'\fR constraint. If the value is not valid, an exception will be
+thrown.
+.PP
+The next \f(CW\*(C`subtype\*(C'\fR, \f(CW\*(C`USZipCode\*(C'\fR, uses
+Regexp::Common. Regexp::Common includes a regex for validating
+\&\s-1US\s0 zip codes. We use this constraint for the \f(CW\*(C`zip_code\*(C'\fR attribute.
+.PP
+.Vb 5
+\&  subtype 'USZipCode'
+\&      => as Value
+\&      => where {
+\&             /^$RE{zip}{US}{\-extended => 'allow'}$/;
+\&         };
+.Ve
+.PP
+Using a subtype instead of requiring a class for each type greatly
+simplifies the code. We don't really need a class for these types, as
+they're just strings, but we do want to ensure that they're valid.
+.PP
+The type constraints we created are reusable. Type constraints are
+stored by name in a global registry. This means that we can refer to
+them in other classes. Because the registry is global, we do recommend
+that you use some sort of pseudo-namespacing in real applications,
+like \f(CW\*(C`MyApp.Type.USState\*(C'\fR.
+.PP
+These two subtypes allow us to define a simple \f(CW\*(C`Address\*(C'\fR class.
+.PP
+Then we define our \f(CW\*(C`Company\*(C'\fR class, which has an address. As we saw
+in earlier recipes, Moose automatically creates a type constraint for
+each our classes, so we can use that for the \f(CW\*(C`Company\*(C'\fR class's
+\&\f(CW\*(C`address\*(C'\fR attribute:
+.PP
+.Vb 1
+\&  has 'address'   => ( is => 'rw', isa => 'Address' );
+.Ve
+.PP
+A company also needs a name:
+.PP
+.Vb 1
+\&  has 'name' => ( is => 'rw', isa => 'Str', required => 1 );
+.Ve
+.PP
+This introduces a new attribute option, \f(CW\*(C`required\*(C'\fR. If an attribute
+is required, then it must be passed to the class's constructor, or an
+exception will be thrown. It's important to understand that a
+\&\f(CW\*(C`required\*(C'\fR attribute can still be false or \f(CW\*(C`undef\*(C'\fR, if its type
+constraint allows that.
+.PP
+The next attribute, \f(CW\*(C`employees\*(C'\fR, uses a \fIparameterized\fR type
+constraint:
+.PP
+.Vb 1
+\&  has 'employees' => ( is => 'rw', isa => 'ArrayRef[Employee]' );
+.Ve
+.PP
+This constraint says that \f(CW\*(C`employees\*(C'\fR must be an array reference
+where each element of the array is an \f(CW\*(C`Employee\*(C'\fR object. It's worth
+noting that an \fIempty\fR array reference also satisfies this
+constraint.
+.PP
+Parameterizable type constraints (or \*(L"container types\*(R"), such as
+\&\f(CW\*(C`ArrayRef[`a]\*(C'\fR, can be made more specific with a type parameter. In
+fact, we can arbitrarily nest these types, producing something like
+\&\f(CW\*(C`HashRef[ArrayRef[Int]]\*(C'\fR. However, you can also just use the type by
+itself, so \f(CW\*(C`ArrayRef\*(C'\fR is legal. (2)
+.PP
+If you jump down to the definition of the \f(CW\*(C`Employee\*(C'\fR class, you will
+see that it has an \f(CW\*(C`employer\*(C'\fR attribute.
+.PP
+When we set the \f(CW\*(C`employees\*(C'\fR for a \f(CW\*(C`Company\*(C'\fR we want to make sure
+that each of these employee objects refers back to the right
+\&\f(CW\*(C`Company\*(C'\fR in its \f(CW\*(C`employer\*(C'\fR attribute.
+.PP
+To do that, we need to hook into object construction. Moose lets us do
+this by writing a \f(CW\*(C`BUILD\*(C'\fR method in our class. When your class
+defined a \f(CW\*(C`BUILD\*(C'\fR method, it will be called immediately after an
+object construction, but before the object is returned to the caller
+(3).
+.PP
+The \f(CW\*(C`Company\*(C'\fR class uses the \f(CW\*(C`BUILD\*(C'\fR method to ensure that each
+employee of a company has the proper \f(CW\*(C`Company\*(C'\fR object in its
+\&\f(CW\*(C`employer\*(C'\fR attribute:
+.PP
+.Vb 8
+\&  sub BUILD {
+\&      my ( $self, $params ) = @_;
+\&      if ( $self\->employees ) {
+\&          foreach my $employee ( @{ $self\->employees } ) {
+\&              $employee\->employer($self);
+\&          }
+\&      }
+\&  }
+.Ve
+.PP
+The \f(CW\*(C`BUILD\*(C'\fR method is executed after type constraints are checked, so
+it is safe to assume that \f(CW\*(C`$self\->employees\*(C'\fR will return an array
+reference, and that the elements of that array will be \f(CW\*(C`Employee\*(C'\fR
+objects.
+.PP
+We also want to make sure that whenever the \f(CW\*(C`employees\*(C'\fR attribute for
+a \f(CW\*(C`Company\*(C'\fR is changed, we also update the \f(CW\*(C`employer\*(C'\fR for each
+employee.
+.PP
+To do this we can use an \f(CW\*(C`after\*(C'\fR modifier:
+.PP
+.Vb 8
+\&  after 'employees' => sub {
+\&      my ( $self, $employees ) = @_;
+\&      if ($employees) {
+\&          foreach my $employee ( @{$employees} ) {
+\&              $employee\->employer($self);
+\&          }
+\&      }
+\&  };
+.Ve
+.PP
+Again, as with the \f(CW\*(C`BUILD\*(C'\fR method, we know that the type constraint
+check has already happened, so we can just check for definedness on the
+\&\f(CW$employees\fR argument.
+.PP
+The \fBPerson\fR class does have demonstrate anything new. It has several
+\&\f(CW\*(C`required\*(C'\fR attributes. It also has a \f(CW\*(C`predicate\*(C'\fR method, which we
+first used in recipe 3.
+.PP
+The only new feature in the \f(CW\*(C`Employee\*(C'\fR class is the \f(CW\*(C`override\*(C'\fR
+method modifier:
+.PP
+.Vb 4
+\&  override 'full_name' => sub {
+\&      my $self = shift;
+\&      super() . ', ' . $self\->title;
+\&  };
+.Ve
+.PP
+This is just a sugary alternative to Perl's built in \f(CW\*(C`SUPER::\*(C'\fR
+feature. However, there is one difference. You cannot pass any
+arguments to \f(CW\*(C`super\*(C'\fR. Instead, Moose simply passes the same
+parameters that were passed to the method.
+.PP
+A more detailed example of usage can be found in
+\&\fIt/000_recipes/moose_cookbook_basics_recipe4.t\fR.
+.SH "CONCLUSION"
+.IX Header "CONCLUSION"
+This recipe was intentionally longer and more complex. It illustrates
+how Moose classes can be used together with type constraints, as well
+as the density of information that you can get out of a small amount
+of typing when using Moose.
+.PP
+This recipe also introduced the \f(CW\*(C`subtype\*(C'\fR function, the \f(CW\*(C`required\*(C'\fR
+attribute, and the \f(CW\*(C`override\*(C'\fR method modifier.
+.PP
+We will revisit type constraints in future recipes, and cover type
+coercion as well.
+.SH "FOOTNOTES"
+.IX Header "FOOTNOTES"
+.IP "(1)" 4
+.IX Item "(1)"
+The value being checked is also passed as the first argument to
+the \f(CW\*(C`where\*(C'\fR block, so it can be accessed as \f(CW$_[0]\fR.
+.IP "(2)" 4
+.IX Item "(2)"
+Note that \f(CW\*(C`ArrayRef[]\*(C'\fR will not work. Moose will not parse this as a
+container type, and instead you will have a new type named
+\&\*(L"ArrayRef[]\*(R", which doesn't make any sense.
+.IP "(3)" 4
+.IX Item "(3)"
+The \f(CW\*(C`BUILD\*(C'\fR method is actually called by \f(CW\*(C`Moose::Object\->BUILDALL\*(C'\fR, which is called by \f(CW\*(C`Moose::Object\->new\*(C'\fR. The \f(CW\*(C`BUILDALL\*(C'\fR
+method climbs the object inheritance graph and calls any \f(CW\*(C`BUILD\*(C'\fR
+methods it finds in the correct order.
+.SH "AUTHORS"
+.IX Header "AUTHORS"
+Stevan Little <stevan@iinteractive.com>
+.PP
+Dave Rolsky <autarch@urth.org>
+.SH "COPYRIGHT AND LICENSE"
+.IX Header "COPYRIGHT AND LICENSE"
+Copyright 2006\-2009 by Infinity Interactive, Inc.
+.PP
+<http://www.iinteractive.com>
+.PP
+This library is free software; you can redistribute it and/or modify
+it under the same terms as Perl itself.