2009-07-07 4 views
21

私は、ロールを使用してMooseに実装されている一連のクラスとインターフェイスを作成しました。私が理解するのが苦労しているのは、ムースの特徴と役割の使い方と実装の正確な違いです。ムースの役割と形質の違いは?

Moose documentation状態:

役割と形質が同じものであることを理解することが重要です。役割は形質として使用でき、形質は役割です。この2つを区別する唯一の点は、特性が短い名前をクラス名に解決できるようにパッケージ化されていることです。言い換えれば、特性によって、呼び出し側は "Big"のような短い名前で参照でき、MooseはMooseX :: Embagen :: Meta :: Attribute :: Role :: Bigのようなクラスに解決します。

私の理解では、形質と役割は「同じ」です。しかし、use Moose -traits 'Foo'構文を使用してアイデアの基本テストを実装すると、私が期待しているようには見えません。確かに私はここで何かを逃しているに違いない。

この最初の例では、(仕事をする)この1と比較すると

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』を見つけることができません」で失敗します。

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

これは、Mooseが "Trait"と "Role"という用語を使用する唯一の違いです。 MooseのドキュメンテーションとAPIでは、「特色」という用語を「 メタクラスに適用されたロール」としばしば使用します。あなたの修正された答えでは、最初の例では MyApp::Userのメタクラスに-traitsでロールを適用し、2番目の例では クラスに適用します。

あなたがあなたの最初の例を変更した場合:

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

あなたが定義されていません。任意の役割を持つ 'x :: Foo'パッケージ。だけではなく、

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'); 

「ショートカット」はムースによって達成される(「クラス文脈」で呼び出された場合)"Moose::Meta::Class::Trait::$trait_name"を探して:ストレートdocumentationからリッピング、我々はregister_implementationが実際に定義されたパッケージの名前を返すことがわかりより短い名前を返す。

+0

私のリビジョンは私の質問を参照してください、私は詳細を追加しようとしました。 – Danny

関連する問題