0

我正在尝试使用Mouse编写一个 perl 模块,在初始化对象之后,但在用户进行任何调用之前,我需要使用用户需要提供的 object2 和 object3 中的两个值来初始化 object1。我尝试使用 Mouse 的after功能来调用 after 的子例程new

package Test;
use strict;
use Mouse;

has 'object1'    => ( is => 'rw', isa => 'Any');
has 'object2'    => ( is => 'ro', isa => 'Str', required => 1); 
has 'object3'    => ( is => 'ro', isa => 'Str', required => 1); 

after 'new' => sub { 
    my ($self) = @_; 
    $self->object1(#do stuff with object2 and object3);
};

1;

但是,目前我收到此错误:

Invalid object instance: 'Test' at lib/Test.pm line 18.

有没有一种方法可以在用户获取返回给他们的对象引用之前使用用户提供的值初始化一个值?

4

1 回答 1

2

鼠标与 Moose 兼容。对象创建具有以下阶段:

  1. BUILDARGS如果定义了参数,则通过该方法传递参数。这可以在 Moose/Mouse 触摸它们之前调整参数,例如提供默认参数或适应关键字约定以外的其他调用样式。
  2. 创建一个新实例并has填充字段(由 声明)。
  3. 该对象现在已设置好并可以使用(从 Mouse/Moose 的角度来看)。您可能对正确设置有不同的想法,并且可以在BUILD方法中执行检查。这是您还可以执行无法用has声明表达的剩余初始化的地方。

所以你的例子可能会变成:

use strict;
use warnings;

package Your::Class;
use Mouse;

has 'object1' => ( is => 'rw', isa => 'Any');
has 'object2' => ( is => 'ro', isa => 'Str', required => 1); 
has 'object3' => ( is => 'ro', isa => 'Str', required => 1); 

sub BUILD { 
    my ($self) = @_; 
    $self->object1($self->object2 . $self->object3);
};

package main;
use Test::More;

# Your::Class->new(object2 => "foo", object3 => "bar");
my $instance = new_ok('Your::Class', [object2 => "foo", object3 => "bar"]);
is($instance->object1, "foobar");

done_testing;

要了解有关 Moose 和 Moose 兼容对象系统中的对象构造的更多信息,请阅读Moose::Manual::Construction

于 2014-01-28T11:05:51.240 回答