2017-04-10 51 views
1

最初的主題開始於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。你會這樣做嗎?如果你能舉一個這個用例的例子,它可能會有幫助 –

回答

2

那麼,問題移動令牌來分隔類和使用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 

如果有人知道更好的解決方案,歡迎您建議它:)