Moose属性未在Builder方法中定义

时间:2016-03-03 17:58:16

标签: perl class oop package moose

我正在使用Moose创建对象,但构建器方法'_initialize_log'无法检索name属性的值。

有没有办法让我只在设置了该属性后运行该方法?

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
****

1 个答案:

答案 0 :(得分:4)

对象仍在构建中!延迟属性的初始化,直到它构建完毕。以下内容延迟了它的初始化,直到它被使用:

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);              # <--
}