2012-08-24 4 views
1

내가 원하는 것을하기에 더 좋은 패턴이 무엇인지 지금 알고 싶습니다. 문제를 최소한으로 줄이기 위해 단계별로 설명하겠습니다.무스 역할 유도

내가 좋아하는 인터페이스 역할이 있습니다

{ 
    package Likeable::OnSelf; 
    use Moose::Role; 

    with 'Likeable'; 

    has 'likers' => (is => 'rw', isa => 'ArrayRef'); 
    sub do_like { } 
} 

{ 
    package Likeable::OnParent; 
    use Moose::Role; 

    with 'Likeable'; 

    requires 'parent'; 

    sub likers { shift->parent->likers(@_) } 
    sub do_like { shift->parent->do_like(@_) } 
} 

및이 후

{ 
    package Likeable; 
    use Moose::Role; 

    requires 'likers'; 
    requires 'do_like'; 
} 

을, 나는 (그들은 모두 구현이 경우) 이전 인터페이스를 반 구현하는 것이이 추상 역할이 필요 나중에 컴파일 할 때이 코드가 필요합니다.

{ 
    package OBJ::OnSelf; 
    use Moose; 
    with 'Likeable::OnSelf'; 
} 

{ 
    package OBJ::OnParent; 
    use Moose; 
    with 'Likeable::OnParent'; 
    has 'parent' => (is => 'rw', isa => 'Obj'); 
} 

foreach my $obj (OBJ::OnSelf->new, OBJ::OnParent->new(parent => OBJ::OnSelf->new)) { 
    if ($obj->does('Likeable')) { 
     $obj->do_like 
    } 
} 

문제는 내가하려는 것입니다. 무스 :: 역할에 대한 파생,하지만 문제를 올바르게 해결하는 방법은 없습니다.

의견이 있으십니까?

+0

특히 정확한 텍스트가 있으면 오류 메시지를 제공해야합니다. 이것을 실행하려 할 때 오류 메시지가 있었어야합니다. – zostay

답변

3

이 문제는 전반적인 역할 조성물을 정말 없다,하지만 난 당신이 같은 오류가 점점 가정

'Likeable::OnParent' requires the method 'parent' to be implemented by 'OBJ::OnParent' at .../Moose/Meta/Role/Application.pm line 51 

문제는 with가에 호출 된 후 has이 방법 accesssor 속성을 만들라고한다는 것입니다을 방법을 확인하십시오. (이것들은 호출되는 서브 루틴이고 실제 언어 구조는 아닙니다.)

내가 아는 몇 가지 좋은 해결책이 있습니다. 나는이 일을 선호 : 속성 (들) 정의 후

package OBJ::OnParent; 
use Moose; 
has 'parent' => (is => 'rw', isa => 'Obj'); 
with 'Likeable::OnParent'; 

with 문을 수행. 내가 아는 다른 옵션이 있습니다 :

package OBJ::OnParent; 
use Moose; 
with 'Likeable::OnParent'; 

BEGIN { 
    has 'parent' => (is => 'rw', isa => 'Obj'); 
} 

BEGIN 블록에 has 호출을 배치하여, 속성은 use Moose 실행 직후 패키지와 with 전에 추가됩니다. 나는 이런 식으로 BEGIN 블록을 고집하는 것을 좋아하지 않지만, 그것은 대부분 개인적인 취향이다.

이 특정한 경우에,하지만, 난 그냥 당신이 더 parent 방법 것 또한 개체 정의를 변경할 필요 우회 Likeable, 반환 지정하도록에 Likeable::OnParent을 변경 제안 할 수 있습니다

package Likeable::OnParent; 
use Moose::Role; 

with 'Likeable'; 

has parent => (
    is => 'rw', 
    does => 'Likeable', 
    required => 1, 
); 

sub likers { shift->parent->likers(@_) } 
sub do_like { shift->parent->do_like(@_) } 

을 이렇게하면 likersdo_like에 대한 호출이 성공해야합니다. 왜냐하면 특성을 설정해야하며 해당 메서드와 문서화 된 계약이 필요한 역할을 구현해야하기 때문입니다.

+0

원본 코드는 다음과 같은 오류 메시지를 표시합니다 : 'Likeable :: OnSelf'는 'likers'가 /usr/local/lib/perl/5.14.2/Moose/Meta/의 'OBJ :: OnSelf'에 의해 구현되어야합니다. 역할/응용 프로그램/ToClass.pm 라인 134. – user1356713

+0

동일한 문제, 다른 패키지, 그럼. 같은 해결책 이죠. – zostay