Moose::...legation(3)
β¨ Moose::Manual::Delegation π β attribute delegation, bestie
okay so this is the Moose::Manual::Delegation page, straight out of the User Contributed Perl Documentation collection, and honestly? it's a bop. it's about attribute delegation, which sounds scary but is literally just "let me call a method and have it secretly call a method on something else." you're gonna love it here. π«Ά
πΈ VERSION πΈ
version 2.4000</purl> β that's the one we're on, no cap.
π WHAT IS DELEGATION? π
Delegation is that feature where you make "proxy" methods that do absolutely nothing except call some other method on an attribute. that's it. that's the whole job. and it slays, because it lets you take a messy pile of "has-a" relationships and present one single unified API from one class. main character energy for your class. β¨
with delegation, anyone using your class doesn't have to know about every single object it's holding inside. less API to learn = less to cry about. π
so here's the vibe: delegations are a mapping between one or more methods from the "real" class (the delegatee, yes that's the actual word, iykyk) and a matching set of methods in the delegating class. and the delegating class can either re-use the delegatee's method names or make up its own. icon behavior.
delegation is also lowkey the best way to wrap a class that already exists β especially a non-Moose class, or one that's somehow hard (or literally impossible) to subclass. π
π DEFINING A MAPPING π
Moose gives you a bunch of options for defining a delegation's mapping, from simple to complex. let's go. π
the simple girl version: an arrayref
the easiest form is just handing over a list of method names:
package Website;
use Moose;
has 'uri' => (
is => 'ro',
isa => 'URI',
handles => [qw( host path )],
);
an arrayref tells Moose: "make me methods in my class that match the method names in the delegated class." periodt.
so with this, we can call $website->host and it "just works". under the hood, Moose calls $website->uri->host for you. β οΈ but note β $website is not automatically passed to the host method. the invocant is $website->uri. that's the detail people miss, don't be that person. π
the rename-your-methods version: a hashref
you can also define the mapping as a hash reference, which lets you rename methods as part of the mapping:
package Website;
use Moose;
has 'uri' => (
is => 'ro',
isa => 'URI',
handles => {
hostname => 'host',
path => 'path',
},
);
a hash tells Moose to create the method names on the left, which then invoke the delegated class methods on the right. so in this example we made a $website->hostname method instead of just stealing URI.pm's name, host, into the Website class. iconic, honestly. β¨
the regex version
these next ones get a lil more complex. first up, regex:
has 'uri' => (
is => 'ro',
isa => 'URI',
handles => qr/^(?:host|path|query.*)/,
);
this is like the array version except it matches the regex against all the methods the delegatee provides. for this to work you must give the attribute an isa parameter, and it has to be a class. Moose uses that to introspect the delegatee class and figure out what methods it's got. no isa, no vibe check, no deal. π
the role version
you can drop a role name in as the value of handles:
has 'uri' => (
is => 'ro',
isa => 'URI',
handles => 'HasURI',
);
Moose introspects the role, sees what methods it provides, and creates a name-for-name mapping for every single one of them. slay.
the sub ref version
finally, you can hand over a sub reference to generate a mapping that behaves like the hash example above. you probably won't need this version often (if ever, fr fr). the Moose docs have more details on exactly how it works if you're feeling brave. π¦
π NATIVE DELEGATION π
native delegations let you delegate to plain old standard Perl data structures as if they were actual objects. yes really. π
has 'queue' => (
traits => ['Array'],
isa => 'ArrayRef[Item]',
default => sub { [ ] },
handles => {
add_item => 'push',
next_item => 'shift',
},
)
the "Array" trait in the traits parameter tells Moose you want the whole set of Array helpers. then Moose creates add_item and next_item methods that "just work". behind the scenes, 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 add_task and 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 like this:
$calendar->add_task( $task_obj );
$calendar->add_appointment( $appointment_obj );
as mentioned above, each trait provides a bunch of methods, summarized below. for more info about any of these provided methods, go read the docs for that specific trait. π
Moose includes the following traits for native delegation:
- Array β the native Array trait provides these methods:
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
- Bool β the native Bool trait provides these methods:
set, unset, toggle, not
- Code β the native Code trait provides these methods:
execute, execute_method
- Counter β the native Counter trait provides these methods:
set, inc, dec, reset
- Hash β the native Hash trait provides these methods:
get, set, delete, keys, exists, defined, values, kv, elements, clear, count, is_empty, accessor, shallow_clone
- Number β the native Number trait provides these methods:
add, sub, mul, div, mod, abs
- String β the native String trait provides these methods:
inc, append, prepend, replace, match, chop, chomp, clear, length, substr
π CURRYING π
currying lets you create a method that already has some parameters pre-set. you can make a curried delegation method like this:
package Spider;
use Moose;
has request => (
is => 'ro'
isa => 'HTTP::Request',
handles => {
set_user_agent => [ header => 'UserAgent' ],
},
)
with that definition, calling $spider->set_user_agent('MyClient') will call $spider->request->header('UserAgent', 'MyClient') behind the scenes. chef's kiss. π
β οΈ heads up bestie: with currying, the currying always starts with the first parameter to a method ($_[0]). any arguments you pass to the delegation come after the curried arguments. don't mix that up.
π MISSING ATTRIBUTES π
it is perfectly valid to delegate methods to an attribute that isn't required, or that can be undefined. but β when a delegated method gets called, Moose will throw a runtime error if the attribute doesn't actually contain an object. so like, it's allowed, just don't be surprised when it yells at you. π
π AUTHORS π
- Stevan Little
<stevan@cpan.org> - Dave Rolsky
<autarch@urth.org> - Jesse Luehrs
<doy@cpan.org> - Shawn M Moore
<sartak@cpan.org> - ΧΧΧΧ Χ§ΧΧ'ΧΧ (Yuval Kogman)
<nothingmuch@woobling.org> - Karen Etheridge
<ether@cpan.org> - Florian Ragwitz
<rafl@debian.org> - Hans Dieter Pearcey
<hdp@cpan.org> - Chris Prather
<chris@prather.org> - Matt S Trout
<mstrout@cpan.org>
π COPYRIGHT AND LICENSE π
this software is copyright (c) 2006 by Infinity Interactive, Inc.
it's free software β you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. π«Ά
and that's a wrap, bestie! π this page lives in perl v5.42.0, dated 2025-07-25, from the Moose::...legation(3) corner of the User Contributed Perl Documentation universe. go forth and delegate. periodt. πβ¨
π¦ where this page comes from
- fedora 43: perl-Moose 2.4000-4.fc43 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms