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

How to initialize classes in constructor using 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 一起工作; hasuse 的替代品吗?如果是这样,我不确定为什么指定的模块没有被实例化(或者可能是??)。

has 不能替代 use;这是完全不同的。 has 在您的 class 中声明了一个属性。

您的声明:

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