在我的对象构造函数中,我有声明同时初始化两个属性:
($self->{token},$self->{token_start}) = $self->_get_authorized_token();
所以我得到了令牌,它在一个声明中一起开始.
现在我尝试移植我的模块使用Moo(se),在这里我不知道我应该如何同时设置这两个绑定属性?一些伪代码就是这样的:
has qw/token token_start/ => ( is => 'rw',default => shift->_get_authorized_token(); );
但是如何在Moo(se)中声明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); }
解决方法
一旦你最终得到两个基本链接到你总是同时设置它们的点的属性……答案通常是创建一个具有两个属性的值对象,然后将相关的方法委托给它.所以,像 –
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
因此,不需要从外部知道值对象的存在,但在内部,您仍然将两个属性绑定在一起,使您的实现将它们作为单个“事物”处理.
– mst