2016-03-03 2 views
1

Я использую Moose для создания объекта, но метод builder '_initialize_log' не может получить значение атрибута name.Moose Attribute Not Defined in Builder Метод

Есть ли способ запустить метод только после того, как этот атрибут был установлен?

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

См. Раздел о лень в [Moose :: Manual :: Attributes] (https://metacpan.org/pod/Moose::Manual::Attributes#Laziness). – ThisSuitIsBlackNot

ответ

4

Объект по-прежнему является одним nstructed! Завершите инициализацию вашего атрибута до тех пор, пока он не будет создан. Следующие задерживает инициализацию, пока она не используется:

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

Возвращаемое значение метода строителя - это значение, которое получает атрибут. Не следует ли строителю «возвращать $ log» вместо этого атрибута? –

+0

@ Hunter McMillen, я предложил * alternatives * использовать атрибут 'builder'. – ikegami

+0

Я имел в виду вашу коррекцию '_initialize_log'. –