在Perl Moose或Moo中的属性代理

问题描述:

最初的主题开始于here,但我需要一个有效的代码示例如何使用Moo或Moose正确地委派属性。在Perl Moose或Moo中的属性代理

基于文档我写了这个代码来检查:

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; 

但这代码产生一个错误:

You cannot overwrite a locally defined method (token) with a delegation at 3.pl line 5

如果我在第5行代码中删除handles => [ qw(token) ]将返回另一个错误:

Deep recursion on subroutine "Tiger::new" at 3.pl line 5.

那该怎么办?

我需要设置Cat::Tiger对象($cat->tiger->token)相同的令牌作为在Cat对象($cat-token)和synс他们每次当Cat对象的令牌改变。

+1

我想既然'Cat'有一个'token'属性,另一个属性(here:'tiger')不能委托已经在'Cat'(这里:'token')中定义的属性。你想达到什么目的? (因为Cat :: Tiger扩展了Cat,并且在构建一个将创建一个新的Cat :: Tiger的Cat时构造一个新的Cat :: Tiger对象,你会得到“深度递归”这将创建一个新的'Cat',等等 –

+0

换句话说,我想实现一个局部'extend':'Cat :: Tiger'包必须只扩展'token Cat'的'token'属性和值' 。可以用Moo或Moose来实现吗? –

+2

我不知道我完全理解,所以'Cat :: Tiger'不应该访问'Cat'的tiger属性,即使它扩展了Cat。你会这样做吗?如果你能举一个这个用例的例子,它可能会有帮助 –

那么,问题移动令牌来分隔类和使用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 

如果有人知道更好的解决方案,欢迎您建议它:)