diff options
Diffstat (limited to 'lib/Moose/Manual/Delegation.pod')
-rw-r--r-- | lib/Moose/Manual/Delegation.pod | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/lib/Moose/Manual/Delegation.pod b/lib/Moose/Manual/Delegation.pod new file mode 100644 index 0000000..0d6210d --- /dev/null +++ b/lib/Moose/Manual/Delegation.pod @@ -0,0 +1,313 @@ +# PODNAME: Moose::Manual::Delegation +# ABSTRACT: Attribute delegation + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Moose::Manual::Delegation - Attribute delegation + +=head1 VERSION + +version 2.1405 + +=head1 WHAT IS DELEGATION? + +Delegation is a feature that lets you create "proxy" methods that do nothing +more than call some other method on an attribute. This lets you simplify a +complex set of "has-a" relationships and present a single unified API from one +class. + +With delegation, consumers of a class don't need to know about all the +objects it contains, reducing the amount of API they need to learn. + +Delegations are defined as a mapping between one or more methods +provided by the "real" class (the delegatee), and a set of +corresponding methods in the delegating class. The delegating class +can re-use the method names provided by the delegatee or provide its +own names. + +Delegation is also a great way to wrap an existing class, especially a +non-Moose class or one that is somehow hard (or impossible) to +subclass. + +=head1 DEFINING A MAPPING + +Moose offers a number of options for defining a delegation's mapping, +ranging from simple to complex. + +The simplest form is to simply specify a list of methods: + + package Website; + + use Moose; + + has 'uri' => ( + is => 'ro', + isa => 'URI', + handles => [qw( host path )], + ); + +Using an arrayref tells Moose to create methods in your class that match the +method names in the delegated class. + +With this definition, we can call C<< $website->host >> and it "just +works". Under the hood, Moose will call C<< $website->uri->host >> for +you. Note that C<$website> is I<not> automatically passed to the C<host> +method; the invocant is C<< $website->uri >>. + +We can also define a mapping as a hash reference. This allows you to +rename methods as part of the mapping: + + package Website; + + use Moose; + + has 'uri' => ( + is => 'ro', + isa => 'URI', + handles => { + hostname => 'host', + path => 'path', + }, + ); + +Using a hash tells Moose to create method names (specified on the left) which +invoke the delegated class methods (specified on the right). + +In this example, we've created a C<< $website->hostname >> method, +rather than simply using C<URI.pm>'s name, C<host> in the Website +class. + +These two mapping forms are the ones you will use most often. The +remaining methods are a bit more complex. + + has 'uri' => ( + is => 'ro', + isa => 'URI', + handles => qr/^(?:host|path|query.*)/, + ); + +This is similar to the array version, except it uses the regex to +match against all the methods provided by the delegatee. In order for +this to work, you must provide an C<isa> parameter for the attribute, +and it must be a class. Moose uses this to introspect the delegatee +class and determine what methods it provides. + +You can use a role name as the value of C<handles>: + + has 'uri' => ( + is => 'ro', + isa => 'URI', + handles => 'HasURI', + ); + +Moose will introspect the role to determine what methods it provides +and create a name-for-name mapping for each of those methods. + +Finally, you can provide a sub reference to I<generate> a mapping that behaves +like the hash example above. You probably won't need this version often (if +ever). See the L<Moose> docs for more details on exactly how this works. + +=head1 NATIVE DELEGATION + +Native delegations allow you to delegate to standard Perl data structures as +if they were objects. + + has 'queue' => ( + traits => ['Array'], + isa => 'ArrayRef[Item]', + default => sub { [ ] }, + handles => { + add_item => 'push', + next_item => 'shift', + }, + ) + +The C<Array> trait in the C<traits> parameter tells Moose that you would like +to use the set of Array helpers. Moose will then create C<add_item> and +C<next_item> methods that "just work". Behind the scenes C<add_item> is +something like + + sub add_item { + my ($self, @items) = @_; + + for my $item (@items) { + $Item_TC->validate($item); + } + + push @{ $self->queue }, @items; + } + +For example, you might use Array helpers to add C<add_task> and +C<add_appointment> methods to a Calendar class: + + has 'tasks' => ( + traits => ['Array'], + isa => 'ArrayRef[Task]', + default => sub { [ ] }, + handles => { + add_task => 'push', + next_task => 'shift', + }, + ); + + has 'appointments' => ( + traits => ['Array'], + isa => 'ArrayRef[Appointment]', + default => sub { [ ] }, + handles => { + add_appointment => 'push', + next_appointment => 'shift', + }, + ); + +Which you would call as: + + $calendar->add_task( $task_obj ); + $calendar->add_appointment( $appointment_obj ); + +As mentioned above, each trait provides a number of methods which are +summarized below. For more information about each of these provided methods +see the documentation for that specific trait. + +Moose includes the following traits for native delegation. + +=over 4 + +=item * L<Array|Moose::Meta::Attribute::Native::Trait::Array> + +The following methods are provided by the native Array trait: + +count, is_empty, elements, get, pop, push, shift, unshift, splice, first, +first_index, grep, map, reduce, sort, sort_in_place, shuffle, uniq, join, set, +delete, insert, clear, accessor, natatime, shallow_clone + +=item * L<Bool|Moose::Meta::Attribute::Native::Trait::Bool> + +The following methods are provided by the native Bool trait: + +set, unset, toggle, not + +=item * L<Code|Moose::Meta::Attribute::Native::Trait::Code> + +The following methods are provided by the native Code trait: + +execute, execute_method + +=item * L<Counter|Moose::Meta::Attribute::Native::Trait::Counter> + +The following methods are provided by the native Counter trait: + +set, inc, dec, reset + +=item * L<Hash|Moose::Meta::Attribute::Native::Trait::Hash> + +The following methods are provided by the native Hash trait: + +get, set, delete, keys, exists, defined, values, kv, elements, clear, count, +is_empty, accessor, shallow_clone + +=item * L<Number|Moose::Meta::Attribute::Native::Trait::Number> + +The following methods are provided by the native Number trait: + +add, sub, mul, div, mod, abs + +=item * L<String|Moose::Meta::Attribute::Native::Trait::String> + +The following methods are provided by the native String trait: + +inc, append, prepend, replace, match, chop, chomp, clear, length, substr + +=back + +=head1 CURRYING + +Currying allows you to create a method with some pre-set parameters. You can +create a curried delegation method: + + package Spider; + use Moose; + + has request => ( + is => 'ro' + isa => 'HTTP::Request', + handles => { + set_user_agent => [ header => 'UserAgent' ], + }, + ) + +With this definition, calling C<< $spider->set_user_agent('MyClient') >> will +call C<< $spider->request->header('UserAgent', 'MyClient') >> behind the +scenes. + +Note that with currying, the currying always starts with the first parameter to +a method (C<$_[0]>). Any arguments you pass to the delegation come after the +curried arguments. + +=head1 MISSING ATTRIBUTES + +It is perfectly valid to delegate methods to an attribute which is not +required or can be undefined. When a delegated method is called, Moose +will throw a runtime error if the attribute does not contain an +object. + +=head1 AUTHORS + +=over 4 + +=item * + +Stevan Little <stevan.little@iinteractive.com> + +=item * + +Dave Rolsky <autarch@urth.org> + +=item * + +Jesse Luehrs <doy@tozt.net> + +=item * + +Shawn M Moore <code@sartak.org> + +=item * + +יובל קוג'מן (Yuval Kogman) <nothingmuch@woobling.org> + +=item * + +Karen Etheridge <ether@cpan.org> + +=item * + +Florian Ragwitz <rafl@debian.org> + +=item * + +Hans Dieter Pearcey <hdp@weftsoar.net> + +=item * + +Chris Prather <chris@prather.org> + +=item * + +Matt S Trout <mst@shadowcat.co.uk> + +=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 |