在我的对象构造函数中,我有一条语句可以同时初始化两个属性:
($self->{token}, $self->{token_start}) = $self->_get_authorized_token();
Run Code Online (Sandbox Code Playgroud)
所以我得到了令牌,并且它在一条语句中一起开始了。
现在我尝试移植我的模块以使用Moo(se),在这里我不知道如何同时设置这两个绑定属性?一些伪代码将是这样的:
has qw/token token_start/ => (
is => 'rw',
default => shift->_get_authorized_token();
);
Run Code Online (Sandbox Code Playgroud)
但是如何以Moo(se)ish方式声明2个绑定属性?
编辑。我展示了该方法的代码_get_authorized_token,也许会带来一些想法:
sub _get_authorized_token {
my $self = shift;
my $postData = { 'apikey' => $self->{key} };
my $url = $self->{base_url} . '/seller';
my $xml = $self->_post(url => $url,
postdata => $postData,
);
my $ref = XMLin($xml, SuppressEmpty => '' );
my $time = $ref->{Notification_Datetime};
my $token = $ref->{Notification_Data}{body}{token};
return ($token, $time);
}
Run Code Online (Sandbox Code Playgroud)
一旦获得了两个基本链接到总是同时设置它们的点的属性,答案通常是创建一个具有两个属性的值对象,然后将相关方法委托给它。因此,类似-
package MyApp::TokenInfo;
use Moo;
has token => (is => 'ro', required => 1);
has token_start => (is => 'ro', required => 1);
...
package MyApp::ThingWithAToken;
use Module::Runtime qw(use_module);
use Moo;
...
has token_info => (is => 'lazy', handles => [ qw(token token_start) ]);
sub _build_token_info {
my ($self) = @_;
my ($token, $token_start) = $self->_get_authorized_token;
# this is equivalent to:
#
# require MyApp::TokenInfo;
# return MyApp::TokenInfo->new(...);
#
# but more concise
return use_module('MyApp::TokenInfo')->new(
token => $token,
token_start => $token_start
);
}
...
my $thing = MyApp::ThingWithAToken->new(...);
$thing->token; # calls $thing->token_info->token;
$thing->token_start; # calls $thing->token_info->token_start
Run Code Online (Sandbox Code Playgroud)
因此,不需要从外部就知道value对象的存在,但是在内部,您仍然将这两个属性捆绑在一起,可以让您的实现将它们作为一个单独的“事物”来处理。
-mst