【问题标题】:Attribute delegation in Perl Moose or MooPerl Moose 或 Moo 中的属性委托
【发布时间】:2017-04-10 16:33:20
【问题描述】:

最初的主题是 here,但我需要一个有效的代码示例,如何使用 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;

但是这段代码会产生错误:

您不能用 a 覆盖本地定义的方法(令牌) 3.pl 第 5 行的委托

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

在 3.pl 第 5 行对子例程“Tiger::new”进行深度递归。

那怎么办呢?

我需要将Cat::Tiger 对象($cat->tiger->token)的令牌设置为与Cat 对象($cat-token)相同,并在每次Cat 对象的令牌更改时同步它们。

【问题讨论】:

  • 我认为由于Cat 有一个token 属性,另一个属性(这里:tiger)不能委托已经在Cat(这里:token)中定义的属性。你想达到什么目的? (你得到“深度递归”错误,因为Cat::Tiger 扩展了Cat 并且你在构造Cat 时构造了一个新的Cat::Tiger 对象,这将创建一个新的Cat::Tiger,这将创建一个新的Cat,等等
  • 换句话说,我想实现部分extendpackage Cat::Tiger 必须仅扩展token 属性和package Cat 的值。可以用 Moo 或 Moose 以某种方式实现吗?
  • 我不确定我是否完全理解。所以Cat::Tiger 不应该有权访问Cattiger 属性,即使它扩展了Cat?为什么要这么做?如果你能举一个这个用例的例子可能会有所帮助
  • 应该的。例如,现在我正在改进我的API::Google 模块。 Cat 类似于API::Google 类,Cat::TigerAPI::Google::GmailAPI::Google::Calendar。我想简化对$gapi->Calendar->CalendarList->list 的API 调用,对于这种方法链接,我需要API::Google::Calendar::CalendarList 实例的令牌属性与API::Google 相同

标签: perl oop inheritance delegation moo


【解决方案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

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

【讨论】:

    猜你喜欢
    • 2014-10-20
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 2022-01-14
    • 2014-12-07
    • 1970-01-01
    相关资源
    最近更新 更多