I have an object which holds a stack of objects. The object represents the current state, and each object in the stack holds the state at a particular level of nesting.
package State;
use Mouse;
use RealState;
has state_stack => {
is => 'rw',
isa => 'ArrayRef[RealState]',
default => sub {
return [RealState->new]
}
};
I want State to delegate to State->state_stack->[0]
. How can I do that efficiently with Mouse (so no meta hacking). I cannot use Moose, my project cannot have any dependencies (I'm bundling Mouse::Tiny).
"You can't" is fine, I'll write an AUTOLOAD
.
You can't it directly, but there's a hack better than AUTOLOAD. That is, RealState->meta->get_all_method_names() gives you method names which are defined in 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();