NAME

MooseX::FunkyAttributes::Role::Attribute::Delegated - delegate an attribute to another object

SYNOPSIS

package Head;

use Moose;

has mouth => (
   is           => 'ro',
   isa          => 'Mouth',
);

package Person;

use Moose;
use MooseX::FunkyAttributes;

has head => (
   is           => 'ro',
   isa          => 'Head',
);

has mouth => (
   is           => 'ro',
   isa          => 'Mouth::Human',
   traits       => [ DelegatedAttribute ],
   delegated_to => 'head',
);

DESCRIPTION

This trait delegates the storage of one attribute's value to the object stored in another attribute. The example in the SYNOPSIS might have been written using Moose's native delegation as:

package Head;

use Moose;

has mouth => (
   is           => 'ro',
   isa          => 'Mouth',
);

package Person;

use Moose;

has head => (
   is           => 'ro',
   isa          => 'Head',
   handles      => [qw( mouth )],
);

However, there are some differences. Using native delegation, mouth will be treated as a method using Moose's introspection API (Person->meta->get_all_methods) and not as an attribute (Person->meta->get_all_attributes). Using this API, mouth is a proper attribute of Person; it just relies on the Head object for storage.

Because mouth is a proper attribute of Person, it can perform delegations of its own; can have its own type constraints, etc.

has mouth => (
   is           => 'ro',
   isa          => 'Mouth::Human',
   traits       => [ DelegatedAttribute ],
   delegated_to => 'head',
   handles      => [qw/ speak kiss vomit eat /], # but not necessarily
);                                               # in that order

Options

delegated_to => STR

The name of the other attribute to delegate this attribute to. This is the only required option.

delegated_accessor => STR

This option may be used if you wish to rename the delegated attribute. For example:

package Person;

has pie_hole => (
   is           => 'ro',
   isa          => 'Mouth::Human',
   traits       => [ DelegatedAttribute ],
   delegated_to => 'head',
   delegated_accessor => 'mouth',
);

Now $person->pie_hole is equivalent to $person->head->mouth.

If omitted, then it is assumed that the attribute has the same name in both classes. If explicitly set to undef, then this assumption is not made, and the accessor is unknown. If the accessor is unknown, then this trait gets somewhat stuck, so you'd need to provide custom_get and custom_set options (see MooseX::FunkyAttributes::Role::Attribute).

delegated_predicate => STR

Like delegated_accessor, but for the attribute's predicate. If omitted, assumes the convention of has_$accessor. An explicit undef can avoid this assumption, but then you'll need to provide custom_has.

delegated_clearer => STR

Like delegated_accessor, but for the attribute's clearer. If omitted, assumes the convention of clear_$accessor. An explicit undef can avoid this assumption, but then you'll need to provide custom_has if you want to define a clearer.

All the custom_blah and custom_inline_blah options from MooseX::FunkyAttributes::Role::Attribute are also available. The delegated_blah options above are essentially just shortcuts for defining them.

Your attribute metaobject has the following methods (in addition to the standard MooseX::FunkyAttributes::Role::Attribute and Moose::Meta::Attribute stuff):

delegated_to
delegated_accessor
delegated_clearer
delegated_predicate

BUGS

Please report any bugs to http://rt.cpan.org/Dist/Display.html?Queue=MooseX-FunkyAttributes.

SEE ALSO

MooseX::FunkyAttributes.

AUTHOR

Toby Inkster <tobyink@cpan.org>.

COPYRIGHT AND LICENCE

This software is copyright (c) 2012-2014 by Toby Inkster.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.

DISCLAIMER OF WARRANTIES

THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.