如何以Mooseish方式声明2个从属属性?

w.k*_*w.k 4 perl moose moo

在我的对象构造函数中,我有一条语句可以同时初始化两个属性:

($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)

use*_*760 5

一旦获得了两个基本链接到总是同时设置它们的点的属性,答案通常是创建一个具有两个属性的值对象,然后将相关方法委托给它。因此,类似-

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