2014-02-03 5 views
1

Рассмотрим следующий пример кода:Атрибут сбруя не удовлетворяет требование роли при использовании Moops и Moose

use Moops; 

role RoleA 
using Moose { 
    requires 'm1'; 
    method m2() { 
    $self->m1." World!\n"; 
    } 
} 

role RoleB 
using Moose { 
    has 'm1' => (accessor => 'm1', is => 'ro', isa => 'Str', default => 'Hello'); 
} 

class ClassA 
with RoleB 
with RoleA 
using Moose { 
    method m3() { 
    $self->m2(); 
    } 
} 

print ClassA->new()->m3(); 

«Компиляция» терпит неудачу, потому что атрибут сбруя, кажется, не удовлетворяют роли запрашивают для m1:

$ perl roletest.pl 
'RoleB|RoleA' requires the method 'm1' to be implemented by 'ClassA' at /usr/lib/perl5/site_perl/Moose/Meta/Role/Application/ToClass.pm line 134. 
    Moose::Meta::Role::Application::ToClass::check_required_methods('Moose::Meta::Role::Application::ToClass=HASH(0x28b9d00)', 'Moose::Meta::Role::Composite=HASH(0x28c6270)', 'Moose::Meta::Class=HASH(0x28ee7c0)') called at /usr/lib/perl5/site_perl/Moose/Meta/Role/Application.pm line 55 
    Moose::Meta::Role::Application::apply('Moose::Meta::Role::Application::ToClass=HASH(0x28b9d00)', 'Moose::Meta::Role::Composite=HASH(0x28c6270)', 'Moose::Meta::Class=HASH(0x28ee7c0)') called at /usr/lib/perl5/site_perl/Moose/Meta/Role/Application/ToClass.pm line 36 
    Moose::Meta::Role::Application::ToClass::apply('Moose::Meta::Role::Application::ToClass=HASH(0x28b9d00)', 'Moose::Meta::Role::Composite=HASH(0x28c6270)', 'Moose::Meta::Class=HASH(0x28ee7c0)', 'HASH(0x28e3410)') called at /usr/lib/perl5/site_perl/Moose/Meta/Role.pm line 470 
    Moose::Meta::Role::apply('Moose::Meta::Role::Composite=HASH(0x28c6270)', 'Moose::Meta::Class=HASH(0x28ee7c0)') called at /usr/lib/perl5/site_perl/Moose/Util.pm line 163 
    Moose::Util::_apply_all_roles('Moose::Meta::Class=HASH(0x28ee7c0)', undef, 'RoleB', 'RoleA') called at /usr/lib/perl5/site_perl/Moose/Util.pm line 99 
    Moose::Util::apply_all_roles('Moose::Meta::Class=HASH(0x28ee7c0)', 'RoleB', 'RoleA') called at /usr/lib/perl5/site_perl/Moose.pm line 66 
    Moose::with('Moose::Meta::Class=HASH(0x28ee7c0)', 'RoleB', 'RoleA') called at /usr/lib/perl5/site_perl/Moose/Exporter.pm line 409 
    Moose::with('RoleB', 'RoleA') called at roletest.pl line 16 
    main::BEGIN() called at roletest.pl line 23 
    eval {...} called at roletest.pl line 23 
BEGIN failed--compilation aborted at roletest.pl line 23. 

Используя простой Moose и Moose::Role это works (как это документально here). Кроме того, не используется базовый код Mooseworks to.

Я уже пробовал переключение порядка with заявлений безрезультатно. Замена атрибута объявлением метода решает проблему, но мне нужен способ указать требования к атрибутам.

Есть ли способ заставить это работать?

ответ

1

Уверены ли вы, что это работает с простым лося? Потому что я попробовал это, и это не удается с очень похожим сообщением об ошибке:

use v5.14; 
use strict; 
use warnings; 

package RoleA { 
    use Moose::Role; 
    requires 'm1'; 
    sub m2 { 
     my $self = shift; 
     $self->m1." World!\n"; 
    } 
} 

package RoleB { 
    use Moose::Role; 
    has 'm1' => (accessor => 'm1', is => 'ro', isa => 'Str', default => 'Hello'); 
} 

package ClassA { 
    use Moose; 
    with qw/ RoleB RoleA /; 
    sub m3 { 
     my $self = shift; 
     $self->m2(); 
    } 
} 

print ClassA->new()->m3(); 

Есть целый ряд вопросов, в Мусе (и соответствующих тестовых случаи TODO в наборе тестов), вращающиеся вокруг атрибутов ролей не удовлетворяющих requires в других ролях. Например, ошибка RT#77406 похожа (хотя и не идентична).

UPDATE вручную сочинял роли один-на-времени, в определенном порядке, вы можете заставить его работать:

use Moops; 

role RoleA using Moose { 
    requires 'm1'; 
    method m2() { 
    $self->m1." World!\n"; 
    } 
} 

role RoleB using Moose { 
    has 'm1' => (is => 'ro', isa => 'Str', default => 'Hello'); 
} 

class ClassA using Moose { 
    with 'RoleB'; 
    with 'RoleA'; 
    method m3() { 
    $self->m2(); 
    } 
} 

print ClassA->new()->m3(); 
+0

Я обновил мой вопрос ссылки мои рабочие примеры: [Moo -Version] (https://gist.github.com/sschober/8784886), [Moose-Version] (https://gist.github.com/sschober/8785012). Единственное различие, которое я вижу, - это указать пакеты с помощью фигурных скобок. – sschober

+0

Aha! Вы составляете роли индивидуально - 'с 'RoleB'; с 'RoleA'; '. Я составляю их вместе - 'с 'RoleB', 'RoleA';'. Это важное различие. Муссы всегда составляют их вместе. Однако см. Раздел «Обновление». – tobyink

 Смежные вопросы

  • Нет связанных вопросов^_^