【问题标题】:How to initialize classes in constructor using Moose如何使用 Moose 在构造函数中初始化类
【发布时间】:2015-03-07 16:15:50
【问题描述】:

我的做法是:

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 的替代品吗?如果是这样,我不确定为什么指定的模块没有实例化(或者可能是??)。

【问题讨论】:

    标签: moose


    【解决方案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

    【讨论】:

    • 谢谢,现在说得通了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-02
    • 2020-02-13
    • 1970-01-01
    • 2021-11-06
    • 2011-02-22
    • 1970-01-01
    相关资源
    最近更新 更多