Делегирование атрибутов в Perl Moose или Moo

Изначально тема была начата здесь, но мне нужен пример работающего кода, как правильно делегировать атрибуты с помощью Moo или Moose.

На основании документации я написал этот код для проверки:

package Cat;
use Moo;

has 'token' => ( is => 'rw', default => '12345' );
has 'tiger' => ( is => 'rw', default => sub { my $self = shift; Cat::Tiger->new(token => $self->token) }, handles => [ qw(token) ] );

package Cat::Tiger;
use Moo;
extends 'Cat';
# + some additional methods


package main;
use Data::Dumper;

my $cat = Cat->new(token=>'54321');
warn $cat->token;
warn $cat->tiger->token;

Но этот код выдает ошибку:

Вы не можете перезаписать локально определенный метод (токен) делегированием в строке 3.pl 5

Если я удалю handles => [ qw(token) ] в строке 5 код вернет еще одну ошибку:

Глубокая рекурсия по подпрограмме "Tiger::new" в строке 3.pl 5.

Так как же это сделать?

Мне нужно установить токен Cat::Tiger объект ($cat->tiger->token) так же, как в Cat объект ($cat-token) и синхронизировать их каждый раз, когда Cat объект изменился.

1 ответ

Итак, проблема решена перемещением токена в отдельный класс и использованием MooX:: Singleton для этого класса:

package Credentials;
use Moo;
with 'MooX::Singleton';
has 'token' => ( is => 'rw', default => '12345' );

package Cat;
use Moo;
has 'credentials' => ( is => 'rw', default => sub { Credentials->instance }, handles => [qw(token)] );
has 'tiger' => ( is => 'rw', default => sub { Cat::Tiger->new(token => shift->token) } );

package Cat::Tiger;
use Moo;
has 'credentials' => ( is => 'rw', default => sub { Credentials->instance }, handles => [qw(token)] );


package main;
use Data::Dumper;
my $cat = Cat->new;
warn $cat->token;
warn $cat->tiger->token;
$cat->token('54321');
warn $cat->token;
warn $cat->tiger->token; # will be also 54321

Если кто-то знает лучшее решение, вы можете предложить его:)

Другие вопросы по тегам