2010-02-15 1 views
3

저는 역할과 그 역할을 혼합 한 몇 가지 클래스가 있습니다. Role 클래스는 구현 클래스를 모두로드하여 Blah를 가져 오는 모든 것이 '사용'행을 많이 입력하지 않고도 사용할 수 있도록합니다.메서드 수정자를 사용하는 역할 응용 프로그램을 내 코드에서 작동시키지 않는 이유는 무엇입니까?

package Blah; 
use Moose::Role; 

use Blah::A; 
use Blah::B; 
(etc...) 

requires '...'; 
requires 'foo'; 
around 'foo' => sub { ... } 

전형적인 ㅋ 서브 클래스의 모든 서브 클래스 '갑'방법은 동일한 코드 비트 시작

package Blah::A; 
use Moose; 
with 'Blah'; 

sub foo { ... } 

__PACKAGE__->meta->make_immutable; 

때문에 역할도하는 방법을 통해 이러한 개질제를 구현한다.

문제는 다음과 같습니다. Moose가 메서드 수정자를 Blah :: * 클래스에 적용하지 않습니다. 클래스에 대한 make_immutable 호출을 제거해도이 문제가 발생합니다. 나는 역할 어플리케이션이 런타임에 완전히 완료되었다고 생각했기 때문에 Blah :: * 클래스가 Blah 전에로드 되었더라도 수정자를 여전히 적용해야합니까?

수정 프로그램이나 다른 방법을 찾고 있습니다. 순간에 Blah는 본질적으로 메서드 수정자를 제외하고는 추상적 인 기본 클래스이므로 역할을 처음 사용하는 이유는 무엇입니까 -하지만 클래스 계층 구조가 더 좋을까요? 미리 감사드립니다.

답변

4

전화 주문이 조금 이상합니다. use blah :: A에 적용되는 역할 내에서 blah :: A를 보내고있는 이유는 무엇입니까?

나는이 use 라인을 꺼내어 실제로 호출자 (들)이 필요한 곳으로 옮기는 것이 좋습니다. 먼저 코드가 작동하도록하고, 그 다음에 많은 use 줄이 사방에 복잡하게 퍼지면 Include 파일로 옮길 수 있습니다.

아니요, 귀하의 가정에 대한 답변에서 역할 응용 프로그램은 이 아니며은 실행 시간에 완료되었지만 with 행에 도달하면 언제든지 완료됩니다. 컴파일시 모듈 use을 컴파일하면 해당 파일이 즉시 컴파일되고 with 행이 실행되고 (그러면 역할이 컴파일되고 실행됩니다). 당연히 런타임에 역할을 적용 할 수도 있습니다 (예 : Moose::Util의 apply_all_roles 참조).하지만 여기서는 발생하지 않습니다.

+0

감사합니다.사용 라인은 짜증나지만, 롤 모듈에 과부하가 걸리지 않고 팩토리 모듈을 쓸 것입니다. :) – rjh

+0

@rjh : 예, 역할을 수행하기 전에 너무 빨리 목표 모듈을로드하는 것입니다. 건물 자체를 완성하고 그 건물에 적용되게합니다. – Ether

-1

나는 당신이 단순히 파일 - 포함과 역할 구성의 차이를 오해한다고 생각합니다. 후드 아래에서

, use 문은 단순히 require를 호출하고 추정 패키지의 import() 문을하고 BEGIN {} 블록에이 모든 것을 포장.

Class :: MOP (CMOP)에서 메타 클래스 메서드로 함수를 설치하지 않습니다. 선언 된 메소드와 임포트 된 메소드 사이에 어떤 차이가 있는지, 또는 CMOP이 차이점을 알려주는 방법은 무엇인지 모르겠다.하지만 이는 add_method을 호출하기 때문에 발생한다. 나는 irc.perl.org/#moose에서 더 많은 정보를 요구할 것이지만 나는 금지되어있다. 바라기를이보기는 당신이 필요로하는 것을 말할 것이다, 또는 당신에게 더 나은 질문을 공식화하기 위하여 정보를 더주십시오. 난 당신이 use 무스 친화적 인 역할로 보내고 패키지를 다시 것 가능하면

package Class; 
use Moose; 
use Carp qw(carp); 

### You have to add the method onto the class. 
Class->meta->add_method('carp' => \&carp); 

around 'carp' => sub { warn "this won't trigger" }; 

package main; 

my $c = Class->new; 
$c->carp('foo'); 

, 그럼 그냥 현재의 역할은 with 문을 사용하여 새 역할을 호출 할 수 있습니다. 역할은 다른 역할 제공 방식을 중심으로 메소드 수정자를 처리합니다.

+1

에반 (Evan) 나는이 질문을 완전히 놓쳤다 고 생각한다. 그는 * 역할을 사용하고 있습니다 (Blah는 무스입니다 :: 역할). 그의 문제는 순환 사용 문 (현재 정의하고있는 역할을 수행하는 클래스를 사용하는 것은 나쁜 M'kay입니까?)과 타이밍 (ether가 가리키는 구성은 '와'가 표시 될 때 발생합니다. 원인 문제). 여기에 예제가 가져 오기를 사용하지 않았고 여기에서했던 것처럼'around' 수정자를 가진 메서드를 완전히 무시하는 예제가 없으므로 여기에 예제가 질문과 관련이 있다는 것을 알 수 없습니다. Rjh는 더 많은 정보를 얻으려고 # 자유롭게 참여할 수 있습니다. – perigrin

+0

방망이로 올라가서, 나는 그 코드가 그것 없이도 작동 할 것이고 (사용을 제거하고 필요로한다)'Blah :: A'를 인스턴스화하기 때문에 그 문제가'use' 사례에 대해 * 특정 *이라고 가정 할 것이다. '주변'이 효과적입니다. 어쩌면 나는 많은 것을 추론하려고 노력했을 것이다. –

관련 문제