2012-05-24 4 views
3

다음은 수수께끼입니다. 저는 Moose :: Role을 인터페이스로 사용합니다. 구체적인 클래스는 역할에 의해 정의 된 필수 속성 빌더를 구현해야합니다. 역할은 또한 속성에 대한 논리를 수행하는 몇 가지 메소드를 정의합니다. 여기에 내가하려는 일의 슬림화 된 버전이 있습니다.무스 :: 역할에 MooseX :: ClassAttribute 액세스

package Parent; 
use Moose::Role; 
requires '_build_permission_level'; 

has 'permission_level' => (
    is => 'ro', 
    isa => Int, 
    lazy_build => 1, 
); 

use constant { 
    LEVEL1 = 1, 
    LEVEL2 = 2, 
    LEVEL3 = 3, 
}; 

sub can_do_action { 
    my $self = shift; 
    return $self->permission_level() >= LEVEL2; 
} 

package Child; 
use Moose; 
with 'Parent'; 

sub _build_permission_level { return Parent->LEVEL3; } 

분명히 다른 권한 등급을 가진 많은 하위 클래스가 있습니다. 이제는 효과가 있습니다. 단점은 비효율적입니다. 모든 하위 인스턴스는 항상 동일한 권한 수준을 갖지만 액션을 수행 할 수 있는지 묻기 위해 인스턴스화해야합니다. 대량으로 10,000 번 실행하면 사진이 생깁니다.

그래서 대신 permission_level을 class 속성으로 지정하고 싶습니다. 효율성 문제를 무스 - y 방식으로 해결합니다. permission_level이 더 이상 $ self를 필요로하지 않음을 주목하십시오.

package Parent; 
use Moose::Role; 
use MooseX::ClassAttribute; 
requires '_build_permission_level'; 

class_has 'permission_level' => (
    is => 'ro', 
    isa => Int, 
    builder => '_build_permission_level', 
); 

use constant { 
    LEVEL1 = 1, 
    LEVEL2 = 2, 
    LEVEL3 = 3, 
}; 

sub can_do_action { 
    return permission_level() >= LEVEL2; 
} 

package Child; 
use Moose; 
with 'Parent'; 

sub _build_permission_level { return Parent->LEVEL3; } 

정의되지 않은 서브 루틴 오류가 발생하여 Parent :: permission_level을 찾을 수 없습니다. 따라서 부모는 permission_level에 대해 알지 못합니다. 정말? 나는 자신의 클래스 속성에 어떻게 접근 할 수 없는지 혼란 스럽다. 나는 정말 간단한 것을 놓치고 있어야합니다. 그러나 더 근본적으로, 부모가 Child가 제공하는 클래스 속성에 대한 논리를 제공하도록하려면 어떻게해야합니까?

답변

2

오류가 나타내는 것은 컴파일 타임에 하위 Parent::permission_level이 없음을 나타냅니다. 그리고 이것은 사실입니다 : hasclass_has은 런타임 구성입니다. can_do_action에있는 호출이 컴파일 될 때 하위가 아직 작성되지 않습니다.

실제 문제는 클래스 메서드를 호출하는 데 잘못된 구문을 사용하고 있다는 것입니다. 따라서 can_do_action을 다시 작성하십시오.

sub can_do_action { 
    my ($class) = @_; 

    return $class->permission_level >= LEVEL2; 
} 

잘 작동합니다. 일반 함수 호출과 달리 메서드 호출은 런타임까지 실행되지 않습니다.이 시점에서 Parent::permission_level이 존재합니다.

+0

그래, 그게 내가 놓치고있는 간단한 일 이었어. 감사! –

관련 문제