Как я могу делегировать первый элемент массива с помощью мыши? - PullRequest
3 голосов
/ 03 ноября 2011

У меня есть объект, который содержит стек объектов.Объект представляет текущее состояние, и каждый объект в стеке хранит состояние на определенном уровне вложенности.

package State;

use Mouse;
use RealState;

has state_stack => {
    is    => 'rw',
    isa   => 'ArrayRef[RealState]',
    default => sub {
        return [RealState->new]
    }
};

Я хочу, чтобы State делегировал State->state_stack->[0].Как я могу сделать это эффективно с Мышь (так что без мета хакерства).Я не могу использовать Moose, мой проект не может иметь никаких зависимостей (я поставляю Mouse :: Tiny).

"Ты не можешь" - хорошо, я напишу AUTOLOAD.

1 Ответ

3 голосов
/ 03 ноября 2011

Вы не можете это сделать напрямую, но есть хак лучше, чем AUTOLOAD. То есть RealState-> meta-> get_all_method_names () предоставляет имена методов, которые определены в RealState.

#!perl
use 5.14.0;
package RealState {
    use Mouse;

    sub foo { 'foo' }
    __PACKAGE__->meta->make_immutable;
}
package State {
    use Mouse;

    has stack => (
        is => 'rw',
        isa => 'ArrayRef',
        default => sub { [ RealState->new ] },
    );

    # define delegates for stack->[0]
    my $meta = __PACKAGE__->meta;
    foreach my $name(RealState->meta->get_all_method_names) {
        next if Mouse::Object->can($name); # avoid 'new', 'DESTROY', etc.

        # say "delegate $name";
        $meta->add_method($name => sub {
            my $self = shift;
            $self->stack->[0]->$name(@_);
        });
    }

    $meta->make_immutable;
}

my $state = State->new();
say $state->foo();
...