21

また、ロールを使用してMooseに実装されるクラスとインターフェイスのセットを作成しました。私が理解するのに苦労しているのは、Mooseの特性と役割の使用法と実装の両方の正確な違いです。

Mooseのドキュメントには次のように記載されています。

役割と特性は同じものであることを理解することが重要です。ロールはトレイトとして使用でき、トレイトはロールです。この2つを区別する唯一の点は、Mooseが短い名前をクラス名に解決できるようにトレイトがパッケージ化されていることです。つまり、トレイトを使用すると、呼び出し元は「Big」のような短い名前でそれを参照でき、MooseはそれをMooseX :: Embiggen :: Meta :: Attribute :: Role::Bigのようなクラスに解決します。

特性と役割は「同じ」であると私は理解しています。ただし、use Moose -traits '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 -traits => 'HasTable';
__PACKAGE__->foo();  #Can't locate object method '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
4

2 に答える 2

12

これは、ムースが「特性」と「役割」という用語を使用する方法の唯一の違いです。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.。これはまさにそれが実行しているはずのことです。

更新:どうやら私はここで正確に正しくありません。トレイトは、インスタンスに適用される役割です。フックは、-traitsHasTableをMyApp::Userのメタクラスインスタンスに適用します。関連するMooseドキュメントを更新しました。

于 2009-07-08T04:24:26.903 に答える
0

パッケージ'x::Foo'をロールで定義しません。ドキュメントから直接リッピングregister_implementationすると、実際に定義されたパッケージの名前が返されることがわかります。

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が"Moose::Meta::Class::Trait::$trait_name"(「クラスコンテキスト」で呼び出されたときに)短い名前を返すだけでなく、検索することによって実現されます。

于 2009-07-07T19:01:43.350 に答える