The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

MooseX::MultiObject - a class that delegates an interface to a set of objects that do that interface

VERSION

version 0.03

SYNOPSIS

    package Role;
    use Moose::Role;
    requires 'some_method';

    package Roles;
    use Moose;
    use MooseX::MultiObject;

    setup_multiobject (
        role => 'Role',
    );

    __PACKAGE__->meta->make_immutable;

    my $object = Class::That::Does::Role->new;
    my $another_object = Another::Class::That::Does::Role->new;

    my @results = map { $_->some_method } ($object, $another_object);

    my $both = Roles->new(
        objects => [$object, $another_object],
    );

    my @results = $both->some_methods; # the same result!

    does_role($object, 'Role'); # true
    does_role($both,   'Role'); # true

DESCRIPTION

Given a role:

    package Some::Role;
    use Moose::Role;
    requires 'foo';
    1;

and some classes that do the role:

    package Class;
    use Moose;
    with 'Some::Role';
    sub foo { ... }
    1;

and something that needs an object that does Some::Role:

    package Consumer;
    use Moose;

    has 'some_roller' => (
        is       => 'ro',
        does     => 'Some::Role',
        requires => 1,
    );

    sub notify_roller { $self->some_roller->foo( ... ) }

    1;

You can say something like:

    Consumer->new( some_roller => Class->new )->notify_roller;

And your roller is notified that foo has occurred. The problem comes when you want two objects to get the message:

    Consumer->new( some_roller => [Class->new, Class->new] )->notify_roller;

That fails, because an array cannot does_role('Some::Role'). That's where MooseX::MultiObject comes in. It can create an object that works like that array:

    package Some::Role::Multi;
    use Moose;
    use MooseX::MultiObject;

    setup_multiobject( role => 'Some::Role' );

    __PACKAGE__->meta->make_immutable;
    1;

Now you can write:

    Consumer->new( some_roller => Some::Role::Multi->new(
        objects => [ Class->new, Class->new ],
    )->notify_roller;

and it works!

EXPORTS

setup_multiobject( %args )

You can pass setup_multiobject class => 'ClassName' instead of role => 'Role', and the class's API role will be used as the role to delegate to. (See MooseX::APIRole for information on API roles.)

METHODS

After calling setup_multiobject, your class becomes able to do the role that you are delegating, and it also becomes able to do MooseX::MultiObject::Role.

add_managed_object

Add an object to the set of objects that the multiobject delegates to.

get_managed_objects

Return a list of the managed objects.

AUTHOR

Jonathan Rockway <jrockway@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2011 by Jonathan Rockway.

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