This commit is contained in:
326
CPAN/Moose/Manual/MooseX.pod
Normal file
326
CPAN/Moose/Manual/MooseX.pod
Normal file
@@ -0,0 +1,326 @@
|
||||
# PODNAME: Moose::Manual::MooseX
|
||||
# ABSTRACT: Recommended Moose extensions
|
||||
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=encoding UTF-8
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Moose::Manual::MooseX - Recommended Moose extensions
|
||||
|
||||
=head1 VERSION
|
||||
|
||||
version 2.2207
|
||||
|
||||
=head1 MooseX?
|
||||
|
||||
It's easy to extend and change Moose, and this is part of what makes
|
||||
Moose so powerful. You can use the MOP API to do things your own way,
|
||||
add new features, and generally customize your Moose.
|
||||
|
||||
Writing your own extensions does require a good understanding of the
|
||||
meta-model. You can start learning about this with the
|
||||
L<Moose::Manual::MOP> docs. There are also several extension recipes
|
||||
in the L<Moose::Cookbook>.
|
||||
|
||||
Explaining how to write extensions is beyond the scope of this
|
||||
manual. Fortunately, lots of people have already written extensions
|
||||
and put them on CPAN for you.
|
||||
|
||||
This document covers a few of the ones we like best.
|
||||
|
||||
=head1 L<MooseX::AttributeHelpers>
|
||||
|
||||
The functionality of this MooseX module has been moved into Moose core.
|
||||
See L<Moose::Meta::Attribute::Native>.
|
||||
|
||||
=head1 L<Moose::Autobox>
|
||||
|
||||
MooseX::AttributeHelpers, but turned inside out, Moose::Autobox provides
|
||||
methods on both arrays/hashes/etc. but also references to them, using
|
||||
Moose roles, allowing you do to things like:
|
||||
|
||||
use Moose::Autobox;
|
||||
|
||||
$somebody_elses_object->orders->push($order);
|
||||
|
||||
Lexically scoped and not to everybody's taste, but very handy for sugaring
|
||||
up other people's APIs and your own code.
|
||||
|
||||
=head1 L<MooseX::StrictConstructor>
|
||||
|
||||
By default, Moose lets you pass any old junk into a class's
|
||||
constructor. If you load L<MooseX::StrictConstructor>, your class will
|
||||
throw an error if it sees something it doesn't recognize;
|
||||
|
||||
package User;
|
||||
|
||||
use Moose;
|
||||
use MooseX::StrictConstructor;
|
||||
|
||||
has 'name';
|
||||
has 'email';
|
||||
|
||||
User->new( name => 'Bob', emali => 'bob@example.com' );
|
||||
|
||||
With L<MooseX::StrictConstructor>, that typo ("emali") will cause a
|
||||
runtime error. With plain old Moose, the "emali" attribute would be
|
||||
silently ignored.
|
||||
|
||||
=head1 L<MooseX::Params::Validate>
|
||||
|
||||
We have high hopes for the future of L<MooseX::Method::Signatures> and
|
||||
L<Moops>. However, these modules, while used regularly in
|
||||
production by some of the more insane members of the community, are
|
||||
still marked alpha just in case backwards incompatible changes need to
|
||||
be made.
|
||||
|
||||
If you don't want to risk that, for now we recommend the decidedly more
|
||||
clunky (but also faster and simpler) L<MooseX::Params::Validate>. This
|
||||
module lets you apply Moose types and coercions to any method
|
||||
arguments.
|
||||
|
||||
package User;
|
||||
|
||||
use Moose;
|
||||
use MooseX::Params::Validate;
|
||||
|
||||
sub login {
|
||||
my $self = shift;
|
||||
my ($password)
|
||||
= validated_list( \@_, password => { isa => 'Str', required => 1 } );
|
||||
|
||||
...
|
||||
}
|
||||
|
||||
=head1 L<MooseX::Getopt>
|
||||
|
||||
This is a role which adds a C<new_with_options> method to your
|
||||
class. This is a constructor that takes the command line options and
|
||||
uses them to populate attributes.
|
||||
|
||||
This makes writing a command-line application as a module trivially
|
||||
simple:
|
||||
|
||||
package App::Foo;
|
||||
|
||||
use Moose;
|
||||
with 'MooseX::Getopt';
|
||||
|
||||
has 'input' => (
|
||||
is => 'ro',
|
||||
isa => 'Str',
|
||||
required => 1
|
||||
);
|
||||
|
||||
has 'output' => (
|
||||
is => 'ro',
|
||||
isa => 'Str',
|
||||
required => 1
|
||||
);
|
||||
|
||||
sub run { ... }
|
||||
|
||||
Then in the script that gets run we have:
|
||||
|
||||
use App::Foo;
|
||||
|
||||
App::Foo->new_with_options->run;
|
||||
|
||||
From the command line, someone can execute the script:
|
||||
|
||||
foo@example> foo --input /path/to/input --output /path/to/output
|
||||
|
||||
=head1 L<MooseX::Singleton>
|
||||
|
||||
To be honest, using a singleton is just a way to have a magic global
|
||||
variable in languages that don't actually have global variables.
|
||||
|
||||
In perl, you can just as easily use a global. However, if your
|
||||
colleagues are Java-infected, they might prefer a singleton. Also, if
|
||||
you have an existing class that I<isn't> a singleton but should be,
|
||||
using L<MooseX::Singleton> is the easiest way to convert it.
|
||||
|
||||
package Config;
|
||||
|
||||
use MooseX::Singleton; # instead of Moose
|
||||
|
||||
has 'cache_dir' => ( ... );
|
||||
|
||||
It's that simple.
|
||||
|
||||
=head1 EXTENSIONS TO CONSIDER
|
||||
|
||||
There are literally dozens of other extensions on CPAN. This is a list
|
||||
of extensions that you might find useful, but we're not quite ready to
|
||||
endorse just yet.
|
||||
|
||||
=head2 L<MooseX::Declare>
|
||||
|
||||
MooseX::Declare is based on L<Devel::Declare>, a giant bag of crack
|
||||
originally implemented by mst with the goal of upsetting the perl core
|
||||
developers so much by its very existence that they implemented proper
|
||||
keyword handling in the core.
|
||||
|
||||
As of perl5 version 14, this goal has been achieved, and modules such
|
||||
as L<Devel::CallParser>, L<Function::Parameters>, and L<Keyword::Simple> provide
|
||||
mechanisms to mangle perl syntax that don't require hallucinogenic
|
||||
drugs to interpret the error messages they produce.
|
||||
|
||||
If you want to use declarative syntax in new code, please for the love
|
||||
of kittens get yourself a recent perl and look at L<Moops> instead.
|
||||
|
||||
=head2 L<MooseX::Types>
|
||||
|
||||
This extension helps you build a type library for your application. It
|
||||
also lets you predeclare type names and use them as barewords.
|
||||
|
||||
use MooseX::Types -declare => ['PositiveInt'];
|
||||
use MooseX::Types::Moose 'Int';
|
||||
|
||||
subtype PositiveInt,
|
||||
as Int,
|
||||
where { $_ > 0 },
|
||||
message { "Int is not larger than 0" };
|
||||
|
||||
One nice feature is that those bareword names are actually namespaced
|
||||
in Moose's type registry, so multiple applications can use the same
|
||||
bareword names, even if the type definitions differ.
|
||||
|
||||
=head2 L<MooseX::Types::Structured>
|
||||
|
||||
This extension builds on top of L<MooseX::Types> to let you declare
|
||||
complex data structure types.
|
||||
|
||||
use MooseX::Types -declare => [ qw( Name Color ) ];
|
||||
use MooseX::Types::Moose qw(Str Int);
|
||||
use MooseX::Types::Structured qw(Dict Tuple Optional);
|
||||
|
||||
subtype Name
|
||||
=> as Dict[ first => Str, middle => Optional[Str], last => Str ];
|
||||
|
||||
subtype Color
|
||||
=> as Tuple[ Int, Int, Int, Optional[Int] ];
|
||||
|
||||
Of course, you could always use objects to represent these sorts of
|
||||
things too.
|
||||
|
||||
=head2 L<MooseX::ClassAttribute>
|
||||
|
||||
This extension provides class attributes for Moose classes. The
|
||||
declared class attributes are introspectable just like regular Moose
|
||||
attributes.
|
||||
|
||||
package User;
|
||||
|
||||
use Moose;
|
||||
use MooseX::ClassAttribute;
|
||||
|
||||
has 'name' => ( ... );
|
||||
|
||||
class_has 'Cache' => ( ... );
|
||||
|
||||
Note however that this class attribute does I<not> inherit like a
|
||||
L<Class::Data::Inheritable> or similar attribute - calling
|
||||
|
||||
$subclass->Cache($cache);
|
||||
|
||||
will set it for the superclass as well. Additionally, class data is usually
|
||||
The Wrong Thing To Do in a strongly OO program since it makes testing a
|
||||
lot harder - consider carefully whether you'd be better off with an object
|
||||
that's passed around instead.
|
||||
|
||||
=head2 L<MooseX::Daemonize>
|
||||
|
||||
This is a role that provides a number of methods useful for creating a
|
||||
daemon, including methods for starting and stopping, managing a PID
|
||||
file, and signal handling.
|
||||
|
||||
=head2 L<MooseX::Role::Parameterized>
|
||||
|
||||
If you find yourself wanting a role that customizes itself for each
|
||||
consumer, this is the tool for you. With this module, you can create a
|
||||
role that accepts parameters and generates attributes, methods, etc. on
|
||||
a customized basis for each consumer.
|
||||
|
||||
=head2 L<MooseX::POE>
|
||||
|
||||
This is a small wrapper that ties together a Moose class with
|
||||
C<POE::Session>, and gives you an C<event> sugar function to declare
|
||||
event handlers.
|
||||
|
||||
=head2 L<MooseX::FollowPBP>
|
||||
|
||||
Automatically names all accessors I<Perl Best Practices>-style,
|
||||
"get_size" and "set_size".
|
||||
|
||||
=head2 L<MooseX::SemiAffordanceAccessor>
|
||||
|
||||
Automatically names all accessors with an explicit set and implicit
|
||||
get, "size" and "set_size".
|
||||
|
||||
=head2 L<MooseX::NonMoose>
|
||||
|
||||
MooseX::NonMoose allows for easily subclassing non-Moose classes with Moose,
|
||||
taking care of the annoying details connected with doing this, such as
|
||||
setting up proper inheritance from Moose::Object and installing
|
||||
(and inlining, at make_immutable time) a constructor that makes sure things
|
||||
like BUILD methods are called.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
=over 4
|
||||
|
||||
=item *
|
||||
|
||||
Stevan Little <stevan@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
Dave Rolsky <autarch@urth.org>
|
||||
|
||||
=item *
|
||||
|
||||
Jesse Luehrs <doy@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
Shawn M Moore <sartak@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org>
|
||||
|
||||
=item *
|
||||
|
||||
Karen Etheridge <ether@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
Florian Ragwitz <rafl@debian.org>
|
||||
|
||||
=item *
|
||||
|
||||
Hans Dieter Pearcey <hdp@cpan.org>
|
||||
|
||||
=item *
|
||||
|
||||
Chris Prather <chris@prather.org>
|
||||
|
||||
=item *
|
||||
|
||||
Matt S Trout <mstrout@cpan.org>
|
||||
|
||||
=back
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
This software is copyright (c) 2006 by Infinity Interactive, Inc.
|
||||
|
||||
This is free software; you can redistribute it and/or modify it under
|
||||
the same terms as the Perl 5 programming language system itself.
|
||||
|
||||
=cut
|
||||
Reference in New Issue
Block a user