如何使用 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 一起工作; has
是 use
的替代品吗?如果是这样,我不确定为什么指定的模块没有被实例化(或者可能是??)。
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 不会自动为您初始化属性(除非您在属性声明中包含一些额外的选项)。您可以使用 default
或 builder
(使用 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。
我的做法是:
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
的替代品吗?如果是这样,我不确定为什么指定的模块没有被实例化(或者可能是??)。
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 不会自动为您初始化属性(除非您在属性声明中包含一些额外的选项)。您可以使用 default
或 builder
(使用 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。