如何使用Moose在构造函数中初始化类

时间:2015-03-07 16:15:51

标签: moose

我这样做的方式是:

package 'My::FH';
use Moose;

has 'csv' => (
 is => 'ro',
 isa => 'Text::CSV',
);

sub store_data {
    my $self = shift;
    ... read lines...
    $self->csv->parse($line);
}

__PACKAGE__->meta->make_immutable;
1;

但是在子程序中调用$self->csv->parse时出现以下错误:

cant call method 'parse' on an undefined value

我并不完全清楚OOP如何与Moose合作;是has的替代use?如果是这样,我不确定为什么指定的模块没有被实例化(或者可能是??)。

1 个答案:

答案 0 :(得分:1)

has不能替代use;它完全不同。 has在您的班级中声明了一个属性。

您的声明:

has 'csv' => (
  is => 'ro',
  isa => 'Text::CSV',
);

只需声明一个名为csv的属性,该属性只读ro且类型为Text::CSV。但类型声明不会为您导入模块。您需要单独use Text::CSV

My :: FH的对象实例还需要对Text :: CSV实例的引用。在代码中的某处,您需要实例化Text :: CSV并将其分配给csv属性。 Moose不会自动为您初始化属性(除非您在属性声明中包含一些额外的选项)。您可以使用defaultbuilder(带lazy)选项来执行此操作:

has csv => (
  is      => 'ro',
  isa     => 'Text::CSV',
  default => sub { Text::CSV->new( { your => 'options' } ) },
);

或者,你可以将它传递给构造函数(虽然我猜这不是你想要的):

my $fh = My::FH->new( csv => Text::CSV->new );

阅读Moose手册的这一部分:https://metacpan.org/pod/Moose::Manual::Attributes