2011-03-21 36 views
1

我在使用BUILD時遇到與此駝鹿有關的錯誤。當我更改爲BUILDALL時,它似乎有效。注意使用的Class::MOP::load_class爲什麼修改BUILD中的Moose類會導致這個錯誤?

使用BUILD

Perl version: 5.012002 
Class::MOP::Version: 1.11 
Moose::Version: 1.24 
Applying fixup GV::WebServer::Fixups::Development 
aflott-g3 at a.pl line 83. 
Error: trying to call refresh() in GV::WebServer::Fixups::Development produced: The  'add_attribute' method cannot be called on an immutable instance at /opt/cidc-perl/perl-5.12.2/lib/perl5/x86_64-linux/Class/MOP/Class/Immutable/Trait.pm line 32 
     Class::MOP::Class::Immutable::Trait::_immutable_cannot_call('add_attribute') called at /opt/cidc-perl/perl-5.12.2/lib/perl5/x86_64-linux/Class/MOP/Class/Immutable/Trait.pm line 37 
     Class::MOP::Class:::around('CODE(0x13a2e028)', 'Class::MOP::Class::Immutable::Moose::Meta::Class=HASH(0x13d58...', 'architecture', 'is', 'ro', 'isa', 'Str', 'lazy', 1, ...) called at /opt/cidc-perl/perl-5.12.2/lib/perl5/x86_64-linux/Class/MOP/Method/Wrapped.pm line 159 
     Class::MOP::Method::Wrapped::__ANON__('Class::MOP::Class::Immutable::Moose::Meta::Class=HASH(0x13d58...', 'architecture', 'is', 'ro', 'isa', 'Str', 'lazy', 1, 'default', ...) called at /opt/cidc-perl/perl-5.12.2/lib/perl5/x86_64-linux/Class/MOP/Method/Wrapped.pm line 89 
     Class::MOP::Class::Immutable::Moose::Meta::Class::add_attribute('Class::MOP::Class::Immutable::Moose::Meta::Class=HASH(0x13d58...', 'architecture', 'is', 'ro', 'isa', 'Str', 'lazy', 1, 'default', ...) called at a.pl line 47 
     Amethyst::SystemInfo::BUILD('Amethyst::SystemInfo=HASH(0x13e83010)', 'HASH(0x13e50cc0)') called at generated method (unknown origin) line 147 
     Amethyst::SystemInfo::new('Amethyst::SystemInfo') called at a.pl line 92 
     GV::WebServer::Fixups::AutoSet::set() called at a.pl line 84 
     GV::WebServer::Fixups::Development::refresh('GV::WebServer::Fixups::Development') called at a.pl line 114 
     main::__ANON__() called at /opt/cidc-perl/perl-5.12.2/lib/perl5/Try/Tiny.pm line 76 
     eval {...} called at /opt/cidc-perl/perl-5.12.2/lib/perl5/Try/Tiny.pm line 67 
     Try::Tiny::try('CODE(0x13e82fe0)', 'Try::Tiny::Catch=REF(0x13e8cd50)') called at a.pl line 118 

使用BUILDALL

Perl version: 5.012002 
Class::MOP::Version: 1.11 
Moose::Version: 1.24 
Applying fixup GV::WebServer::Fixups::Development 
aflott-g3 at a.pl line 71. 
aflott-g3364136 at a.pl line 81. 

完整的錯誤

從這個代碼:

package Amethyst::SystemInfo; 

use v5.10; 

use Moose; 

use Sys::Hostname qw(); 
use Sys::HostIP; 
use Try::Tiny; 

has '_host_ip' => ('is' => 'ro', 'isa' => 'Sys::HostIP', 'default' => sub { Sys::HostIP->new }); 
has 'eth0_ipv4' => ('is' => 'rw', 'isa' => 'Str',); 
has 'ethernet_interfaces' => ('is' => 'rw', 'isa' => 'HashRef',); 
has 'hostname' => ('is' => 'ro', 'isa' => 'Str', 'default' => sub { Sys::Hostname::hostname }); 

sub BUILD { 
    my ($self) = @_; 

    $self->ethernet_interfaces($self->_host_ip->interfaces); 

    if ($self->ethernet_interfaces->{'eth0'}) { 
     $self->eth0_ipv4($self->ethernet_interfaces->{'eth0'}); 
    } 

    foreach my $attrib (
     qw(architecture domain fqdn kernel kernelrelease kernelversion memorytotal operatingsystem processor processorcount swap) 
    ) { 
     $self->meta->add_attribute(
      $attrib => (
       'is'  => 'ro', 
       'isa'  => 'Str', 
       'lazy' => 1, 
       'default' => sub { return $self->_load_value($attrib) } 
      ) 
     ); 
    } 

    $self->meta->make_immutable; 

    return; 
} 

sub _load_value { 
    my ($self, $module_name) = @_; 

    try { 
     Class::MOP::load_class("Pfacter::$module_name"); 
    } 
    catch { 
     warn("Failed to load Pfacter::$module_name"); 
    }; 

    my $value = "Pfacter::$module_name"->pfact({'pfact' => {'kernel' => 'Linux'}}); 

    unless (defined($value)) { 
     warn("finding value for $module_name returned undef"); 
    } 

    chomp($value); 

    return $value; 
} 

no Moose; 

package GV::WebServer::Fixups::Development; 

use v5.10; 

sub refresh { 
    warn Amethyst::SystemInfo->new->hostname; 
    return GV::WebServer::Fixups::AutoSet::set(); 
} 

package GV::WebServer::Fixups::AutoSet; 

use v5.10; 

sub set { 
    my $sysinfo = Amethyst::SystemInfo->new; 
    warn $sysinfo->hostname, ' ', $sysinfo->swap; 
} 

package main; 

use v5.10; 

use Class::MOP; 
use Try::Tiny; 

my $module_name = "GV::WebServer::Fixups::Development"; 

say('Perl version: ',  $]); 
say('Class::MOP::Version: ', $Class::MOP::VERSION); 
say('Moose::Version: ',  $Moose::VERSION); 
say("Applying fixup $module_name"); 

Class::MOP::load_class($module_name); 

my $ret; 
try { 
    $ret = $module_name->refresh; 
} 
catch { 
    warn("Error: trying to call refresh() in $module_name produced: " . shift); 
}; 
+2

你爲什麼要修改對象構建時間的類?你想達到什麼目的? – phaylon 2011-03-21 15:45:01

+0

所以我不需要複製/粘貼/稍微編輯11個屬性。我在建築時修改班的印象是好的? – 2011-03-21 16:06:42

+2

您實際上正在嘗試在構建對象時修改類。請注意'has'只是次級調用,所以你可以在它周圍編寫任意代碼(類似於BUILD中的代碼)。 – bvr 2011-03-21 16:17:34

回答

7

每當您構建該類的對象時,您正在修改。這是沒有意義的。只需將您的班級建設代碼從BUILDBUILDARGS中移出,並將其與其他班級建築代碼一起放入。

package Amethyst::SystemInfo; 

use v5.10; 

use Moose; 

use Sys::Hostname qw(); 
use Sys::HostIP; 
use Try::Tiny; 

has '_host_ip' => ('is' => 'ro', 'isa' => 'Sys::HostIP', 'default' => sub { Sys::HostIP->new }); 
has 'eth0_ipv4' => ('is' => 'rw', 'isa' => 'Str',); 
has 'ethernet_interfaces' => ('is' => 'rw', 'isa' => 'HashRef',); 
has 'hostname' => ('is' => 'ro', 'isa' => 'Str', 'default' => sub { Sys::Hostname::hostname }); 

foreach my $attrib (qw(
    architecture domain fqdn kernel kernelrelease kernelversion 
    memorytotal operatingsystem processor processorcount swap 
)) { 
    has $attrib => (
     'is'  => 'ro', 
     'isa'  => 'Str', 
     'lazy' => 1, 
     'default' => sub { return $_[0]->_load_value($attrib) }, 
    ); 
} 

sub BUILD { 
    my ($self) = @_; 

    $self->ethernet_interfaces($self->_host_ip->interfaces); 

    if ($self->ethernet_interfaces->{'eth0'}) { 
     $self->eth0_ipv4($self->ethernet_interfaces->{'eth0'}); 
    } 
} 

sub _load_value { 
    ... 
} 

no Moose; 
__PACKAGE__->meta->make_immutable; 

1; 

phanth和bvr的榮譽。

+0

Doh!我應該知道這一點。謝謝! – 2011-03-21 18:01:24

相關問題