0

我收到一个编译时错误(Moose 抱怨修改不可变实例)在包上运行“perl -c”,但使用该包的代码运行无错误。示例代码:

文件 Pa_1.pm(使用 MooseX::Aliases 和包 Pa_2.pm 的不可变 Moose 类):

package Pa_1;

use Pa_2;

use Moose;

# uncommenting either this line ...
use MooseX::Aliases;

# ... or this line to make 'perl -c' work
__PACKAGE__->meta->make_immutable;

1;

文件 Pa_2.pm(仅使用使用 Pa_2.pm 的 Pa_1.pm):

package Pa_2;

use Pa_1;
1;

文件 run_pa_1.pl :

#!/usr/bin/env perl

use Pa_1;

my $pa1 = Pa_1->new();
print "Done !\n";

执行 run_pa_1.pl 有效,但 'perl -c Pa_1.pm' 给出

The 'add_method' method cannot be called on an immutable instance at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Class/MOP/Class/Immutable/Trait.pm line 32.
        Class::MOP::Class::Immutable::Trait::_immutable_cannot_call('add_method') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Class/MOP/Class/Immutable/Trait.pm line 47
        Class::MOP::Class:::around('CODE(0xc10158)', 'Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'DESTROY', 'Moose::Meta::Method::Destructor=HASH(0x14af4f8)') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Class/MOP/Method/Wrapped.pm line 162
        Class::MOP::Method::Wrapped::__ANON__('Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'DESTROY', 'Moose::Meta::Method::Destructor=HASH(0x14af4f8)') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Class/MOP/Method/Wrapped.pm line 91
        Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::SERIAL::1::add_method('Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'DESTROY', 'Moose::Meta::Method::Destructor=HASH(0x14af4f8)') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Class/MOP/Mixin/HasMethods.pm line 181
        Class::MOP::Mixin::HasMethods::_restore_metamethods_from('Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Class/MOP/Class.pm line 405
        Class::MOP::Class::_restore_metaobjects_from('Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Moose/Meta/Class.pm line 728
        Moose::Meta::Class::_restore_metaobjects_from('Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Class/MOP/Class.pm line 65
        Class::MOP::Class::reinitialize('Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'error_class', 'Moose::Error::Default', 'wrapped_method_metaclass', 'Class::MOP::Method::Wrapped', 'instance_metaclass', 'Moose::Meta::Instance', 'method_metaclass', ...) called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Moose/Meta/Class.pm line 188            Moose::Meta::Class::reinitialize('Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'attribute_metaclass', 'Moose::Meta::Class::__ANON__::SERIAL::2') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Moose/Util/MetaRole.pm line 99            Moose::Util::MetaRole::_make_new_metaclass('Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'HASH(0x144f868)', 'class') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Moose/Util/MetaRole.pm line 28            Moose::Util::MetaRole::apply_metaroles('for', 'Class::MOP::Class::Immutable::Moose::Meta::Class::__ANON__::S...', 'class_metaroles', 'HASH(0x144f868)', 'role_metaroles', 'HASH(0x144f838)') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Moose/Exporter.pm line 543
        Moose::Exporter::_apply_metaroles('Pa_1', 'ARRAY(0x93c630)', 'CODE(0xddccc8)') called at /home/pecho/perl5/perlbrew/perls/perl-5.16.1/lib/site_perl/5.16.1/x86_64-linux/Moose/Exporter.pm line 460
        Moose::Exporter::__ANON__('MooseX::Aliases') called at Pa_1.pm line 6
        Pa_1::BEGIN() called at Pa_1.pm line 6
        eval {...} called at Pa_1.pm line 6
BEGIN failed--compilation aborted at Pa_1.pm line 6.

我有点困惑,因为在 Pa_2.pm 上使用编译开关启动 perl 时会发出错误,但运行时间似乎没问题。

  • 在调试器中并执行“使用 Pa_2”也没有错误。
  • 执行 'perl -c run_pa_1.pl' 也没有错误。
  • 不使用 MooseX::Aliases 或不使 Pa_1.pm 不可变让 'perl -c Pa_1.pm' 编译没有错误。

代码中是否存在错误,在 MooseX::Aliases 中还是 Moose 内部的东西?

使用的版本:perl 5.16.1;驼鹿 2.0604; MooseX::别名 0.10;

4

2 回答 2

1

永远不要直接执行模块。你最终编译并执行了两次。

同样,永远不要直接编译模块。你最终编译了两次。

perl -c Pa_1.pm

应该

perl -c -e'use Pa_1;'

perl -c Pa_1.pm执行以下操作(忽略require并且import什么都不做):

package Pa_1;
require Pa_2;

package Pa_2;
require Pa_1;

package Pa_1;
require Moose;
import Moose;
require MooseX::Aliases;
import MooseX::Aliases;
__PACKAGE__->meta->make_immutable;
1;

package Pa_2;
1;

package Pa_1;
import Moose;
import MooseX::Aliases;

perl -c -e'use Pa_1;执行以下操作(忽略require并且import什么都不做):

package Pa_1;
require Pa_2;

package Pa_2;
1;

package Pa_1;
require Moose;
import Moose;
require MooseX::Aliases;
import MooseX::Aliases;
__PACKAGE__->meta->make_immutable;
1;

注意你最终是如何做的

import Moose;
import MooseX::Aliases;

做完之后

__PACKAGE__->meta->make_immutable;

当你做错了?

于 2012-11-05T21:38:33.750 回答
0

Pa_1.pm 中的这种排序对您有用吗?

package Pa_1;

use Moose;
use MooseX::Aliases;

use Pa_2;

__PACKAGE__->meta->make_immutable;

我认为通常建议将所有Moose模块放在首位。

于 2012-11-05T15:31:27.923 回答