2009-07-07 3 views
21

역할을 사용하여 Moose에 구현 된 클래스 및 인터페이스 집합을 작성했습니다. 내가 이해하는데 어려움을 겪고있는 것은 무스 특성과 역할의 사용과 구현의 정확한 차이입니다.무스에서 역할과 형질은 어떻게 다릅니 까?

Moose documentation 상태 :

역할과 특성이 똑같은 것을 이해하는 것이 중요합니다. 역할은 특성으로 사용될 수 있고 특성은 역할입니다. 두 가지를 구별하는 유일한 점은 특성이 짧은 이름을 클래스 이름으로 해석 할 수있는 방법으로 패키지되어 있다는 것입니다. 바꾸어 말하면, 호출자는 "Big"과 같은 짧은 이름으로 참조 할 수 있습니다. Moose는이를 MooseX :: Embiggen :: Meta :: Attribute :: Role :: Big와 같은 클래스로 변환합니다.

특성과 역할은 "동일합니다"라고 알고 있습니다. 그러나, use Moose -traits 'Foo' 구문을 사용하여 아이디어의 기본 테스트를 구현할 때 내가 기대하는 것처럼 보이지 않습니다. 확실하게 나는 여기에서 무엇인가 놓치고있을 것임에 틀림 없다.

package MyApp::Meta::Class::Trait::HasTable; 
use Moose::Role; 
sub foo { warn 'foo' } 

package Moose::Meta::Class::Custom::Trait::HasTable; 
sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' } 

package MyApp::User; 
use Moose; 
with 'MyApp::Meta::Class::Trait::HasTable'; 
__PACKAGE__->foo(); #foo 

답변

12

이것은 무스가 "특성"과 "역할"이라는 용어를 사용하는 유일한 차이점입니다. 무스의 문서 및 API에서는 종종 "특성"이라는 용어를 " 을 메타 랭크에 적용된 역할"로 사용합니다. 수정 된 답변에서 첫 번째 예는 역할을 -traits을 통해 MyApp::User의 메타 클래스에 적용하고 두 번째 예는 클래스에 적용합니다.

당신이 당신의 첫 번째 예제 변경하는 경우 :

package MyApp::Meta::Class::Trait::HasTable; 
use Moose::Role; 
sub foo { warn 'foo' } 

package Moose::Meta::Class::Custom::Trait::HasTable; 
sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' } 

package MyApp::User; 
use Moose -traits => 'HasTable'; 
__PACKAGE__->meta->foo(); 

을 당신이 에 가정 일을 정확히 어느 "foo at [script]. line 3."를 볼 수 있습니다.

업데이트 : 분명히 여기 정확히 정확하지 않습니다. 특성은 인스턴스에 적용되는 역할입니다. -traits 훅은 MyApp :: User의 메타 클래스 인스턴스에 HasTable을 적용합니다. 관련 Moose 문서를 업데이트했습니다.

+0

고마워, 그게 내가보고 있던 행동을 설명해 준다. – Danny

+1

이 차이를 약간 반영하기 위해 Extending/Recipe1.pod의 텍스트를 업데이트했습니다. 또한 것들을 혼란스럽게하는 참고 사항 Scala와 같은 다른 언어에서는 역할과 비슷한 것을 Traits이라 부릅니다. 이러한 특성은 Moose의 역할 구현의 기원을 알 수 있지만 상태 전달 기능이 부족한 일부 논문에서 정의됩니다 (즉, 메소드는 속성이며 속성이 없습니다). – perigrin

0

당신은 정의하지 않습니다

이 첫 번째 예는 (작동하지 않습니다)이 하나에 비해

package MyApp::Meta::Class::Trait::HasTable; 
use Moose::Role; 
sub foo { warn 'foo' } 

package Moose::Meta::Class::Custom::Trait::HasTable; 
sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' } 

package MyApp::User; 
use Moose -traits => 'HasTable'; 
__PACKAGE__->foo(); #Can't locate object method 'foo' 

" 'foo는'객체 메소드를 찾을 수 없습니다"와 함께 실패 모든 역할을 가진 'x :: Foo'패키지. documentation에서 바로 찢어, 우리는 볼이 register_implementation 다시 표시 실제로 정의 된 패키지의 이름 :

은 "바로 가기"(A "클래스 컨텍스트"에서 호출) "Moose::Meta::Class::Trait::$trait_name"을 찾고 무스에 의해 달성된다
package MyApp::Meta::Class::Trait::HasTable; 
use Moose::Role; 

has table => (
    is => 'rw', 
    isa => 'Str', 
); 

package Moose::Meta::Class::Custom::Trait::HasTable; 
sub register_implementation { 'MyApp::Meta::Class::Trait::HasTable' } 

package MyApp::User; 
use Moose -traits => 'HasTable'; 

__PACKAGE__->meta->table('User'); 

뿐만 아니라 더 짧은 이름을 되 돌린다.

+0

내 개정판을 참고하십시오. 자세한 내용을 추가하려고했습니다. – Danny

관련 문제