How to use delegation with handles in Perl Moose?
Question
How to use delegation with handles in Perl Moose?
In Perl's Moose object system, delegation is a powerful technique to forward method calls from one class to another wrapped object or attribute. Moose provides a convenient handles feature for attributes, allowing you to automatically delegate methods to the attribute's object without having to manually write forwarding methods.
What is Delegation with Handles in Moose?
Delegation means your object passes responsibility for some methods to an internal object it holds. Moose's handles lets you specify which methods from the attribute's class you want your class to "inherit" or expose transparently, reducing boilerplate.
For example, if your class has an attribute holding a HashRef, and you want to provide hash-like methods such as get, set, or keys directly on your object, handles makes it very easy.
Using handles with Moose Attributes
Moose attributes are declared with has. The handles option defines what methods from the attribute's class or role will be delegated. You can pass one of:
handles => 'method_name'- delegate a single method by the same namehandles => [ 'method1', 'method2' ]- delegate multiple methodshandles => { new_name => 'original_name', ... }- alias or rename delegated methods
Example: Delegation with handles in Moose
Below is a runnable example demonstrating delegation to a HashRef-like object. The class My::Config stores configuration in a hash reference and delegates get/set operations to the internal hash attribute.
use strict;
use warnings;
use 5.010;
use Moose;
package My::Config {
use Moose;
# The 'config' attribute holds a hashref
has 'config' => (
is => 'rw',
isa => 'HashRef',
default => sub { {} },
traits => ['Hash'], # Use Moose's Hash trait for native delegation
handles => {
get_value => 'get', # delegate 'get' method to 'get_value'
set_value => 'set', # delegate 'set' method to 'set_value'
all_keys => 'keys', # delegate 'keys' method to 'all_keys'
count_values => 'count', # delegate 'count' method to 'count_values'
},
);
}
# Usage
my $conf = My::Config->new();
$conf->set_value('foo' => 42);
$conf->set_value('bar' => 99);
say "foo = ", $conf->get_value('foo');
say "bar = ", $conf->get_value('bar');
say "Keys stored: ", join(", ", $conf->all_keys);
say "Number of keys: ", $conf->count_values;
Explanation
- The attribute
configis aHashRefsupporting delegation via theHashnative trait provided by Moose. - The
handleshashes method names from the hash trait to the class methods, optionally renaming them for clarity. - Calling
$conf->set_value('foo' => 42)delegates to$conf->config->set('foo', 42). - You can access the underlying hash functionality transparently through your class interface without manually writing methods.
Additional Notes and Pitfalls
- Traits: Delegation like this requires the appropriate native trait (e.g.,
Hash,Array, orString) to be set on the attribute. Otherwise, methods likegetorsetwon't exist. - Method Naming: You can rename delegated methods via the hashref form of
handlesto avoid collisions and improve readability. - Moose version: Native traits and
handleshave been stable since Perl 5.10 and Moose 2.x; make sure you have these or newer for best support. - Readonly Attributes: Delegation can be used with
roattributes too, but write methods won't work. - Overriding: If you need custom behavior, you can override delegated methods after declaration.
Summary
Delegation with handles in Moose is a concise, expressive way to expose functionality from contained objects or native traits on attributes. It reduces boilerplate and keeps your classes clean and focused on their own logic.
Remember to use the right trait (like Hash, Array) when delegating to native Perl data structures, and you can rename methods to your liking.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 170ms
foo = 42
bar = 99
Keys stored: foo, bar
Number of keys: 2
(empty)Was this helpful?
Related Questions
- How to use Moose::Util::TypeConstraints for custom types?
- How to implement method delegation in Perl Moo?
- How to use Type::Tiny with Moo for strict typing in Perl?
- How to use required attributes in Perl Moo and Moose?
- How to convert a Perl Moo class to Moose?
- How to use Moo lazy_build for attribute defaults in Perl?