Moose的角色和特质有何不同?

Dan*_*nny 21 perl moose

我编写了一组使用角色在Moose中实现的类和接口.我无法理解的是Moose特征与角色的使用和实现的确切差异.

驼鹿文件规定:

重要的是要理解角色和特征是一回事.角色可以用作特征,特征是角色.区分这两者的唯一方法是以一种让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'
Run Code Online (Sandbox Code Playgroud)

与此相比(确实有效):

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
Run Code Online (Sandbox Code Playgroud)

per*_*rin 12

这是Moose如何使用术语"特质"和"角色"的唯一区别.Moose的文档和API经常使用术语"traits"作为"应用于元类的角色".在您的修订答案中,您的第一个示例将角色应用于 MyApp::User元类通过-traits,第二个示例将其应用于类.

如果您将第一个示例更改为:

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();
Run Code Online (Sandbox Code Playgroud)

你会看到" foo at [script]. line 3."这正是它应该做的.

更新:显然我在这里并不完全正确.特征是应用于实例的角色.该-traits钩适用HasTable为MyApp的::用户的元类的实例.我已经更新了相关的Moose文档.