
MooX::Attributes::Shadow - shadow attributes of contained objects

# shadow Foo's attributes in Bar
package Bar;
use Moo;
use Foo;
use MooX::Attributes::Shadow ':all';
# create attributes shadowing class Foo's a and b attributes, with a
# prefix to avoid collisions.
shadow_attrs( 'Foo',
attrs => [ qw( a b ) ],
fmt => sub { 'pfx_' . shift },
);
# later in the code, use the attributes when creating a new Foo
# object.
sub create_foo {
my $self = shift;
my $foo = Foo->new( xtract_attrs( Foo => $self ) );
}

Container classes (which contain other objects) at times need to reflect the contained objects' attributes in their own attributes.
For example, if class Foo has attribute a, and class Bar contains and instantiates class Foo, it may need to provide a means of specifying a value for Foo's a attribute.
Typically, one might do this:
package Bar;
use Moo;
use Foo;
has a => ( is => 'ro' );
has foo => ( is => 'ro',
lazy => 1,
default => sub { Foo->new( shift->a ) }
);
This is tedious when more than one attribute is propagated. If Bar has its own a attribute, then one must do more work to avoid name space collisions.
MooX::Attributes::Shadow provides a means to reducing the agony. It automatically creates attributes which shadow contained objects' attributes and easily extracts them for subsequent use.
A contained class can use MooX::Attributes::Shadow::Role to simplify things even further, so that container classes using it need not know the names of the attributes to shadow.

shadow_attrs( $contained_class, attrs => \@attrs, %options );
Create read-only attributes for the attributes in @attrs and associate them with $contained_class. There is no means of specifying additional attribute options.
It takes the following options:
This is a reference to a subroutine which should return a modified attribute name (e.g. to prevent attribute collisions). It is passed the attribute name as its first parameters.
In the case where more than one instance of an object is contained, this is used to identify an individual instance.
If true, the actual attribute name is mangled; the attribute initialization name is left untouched (see the init_arg option to the Moo has subroutine). This defaults to true.
$attrs = shadowed_attrs( $contained, $container, $instance );
Return a hash of attributes shadowed from $contained into $container. $contained and $container may either be a class name or an object. The $instance parameter is optional, and indicates the contained object instance whose attributes should be extracted.
The hash keys are the attribute names in the contained class; the hash values are the attribute names in the container class.
%attrs = xtract_attrs( $contained, $container_obj, $instance );
After the container class is instantiated, xtract_attrs is used to extract attributes for the contained object from the container object. $contained may be either a class name or an object in the contained class.
The $instance parameter is optional, and indicates the contained object instance whose attributes should be extracted.

Copyright 2012 Smithsonian Astrophysical Observatory
This software is released under the GNU General Public License. You may find a copy at
http://www.fsf.org/copyleft/gpl.html

Diab Jerius <djerius@cfa.harvard.edu>