生成器方法中未定义 Moose 属性

Moose Attribute Not Defined in Builder Method

我正在使用 Moose 创建对象,但生成器方法“_initialize_log”无法检索名称属性的值。

只有在设置该属性后,我才能运行该方法吗?

EFT.pm

package EFT;
use Moose;

# Attributes
has name => (
    is       => "ro",
    isa      => "Str",
    required => 1
);

has log => (
    is      => 'rw',
    isa     => 'Str',
    builder => '_initialize_log'
);

sub _initialize_log
{
    $self->{'log'} = "****\n";
    $self->{'log'} .= $self->{'name'} . "\n";
    $self->{'log'} .= `date`;
    $self->{'log'} .= "****\n";
}

test.pl

#!/usr/bin/perl

use strict;
use warnings;
use EFT;

# Constants
use constant NAME => 'Test Script';

# Create script object
my $script = EFT->new(name => NAME);

print $script->{'log'};

输出

Use of uninitialized value in concatenation (.) or string at EFT.pm line 46.
****

Thu Mar  3 12:54:31 EST 2016
****

对象还在构造中!延迟属性的初始化,直到它构造完成。以下延迟它的初始化直到它被使用:

lazy => 1

您也可以改用 BUILD 方法。

sub BUILD {
   my $self = shift;
   $self->_initialize_log();
}

请注意,您在 _initialize_log 中存在三个错误:

sub _initialize_log
{
    my $self = shift;              # <-- Won't even compile without this!
    my $log = "****\n";
    $log .= $self->name . "\n";    # <-- Removed reliance on Moose internals
    $log .= `date`;
    $log .= "****\n";
    return $log;                   # <-- The value is to be returned.
}

要从 BUILD 而不是作为生成器调用它,您需要按如下方式更改它:

sub _initialize_log
{
    my $self = shift;
    my $log = "****\n";
    $log .= $self->name . "\n";
    $log .= `date`;
    $log .= "****\n";
    $self->log($log);              # <--
}