2009-07-07 47 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 -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 

回答

12

这是穆斯如何使用术语“特质”和“角色”的唯一区别。 Moose的文档和API经常使用术语“特征”作为“应用于Metaclasses的角色 ”。在您的修订答案中,第一个示例通过-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挂钩将HasTable应用于MyApp :: User的元类实例。我已经更新了相关的Moose文档。

+0

谢谢,这解释了我所看到的行为。 – Danny 2009-07-08 13:40:55

0

你没有定义包含任何角色的'x :: Foo'。从documentation直接撕开,我们看到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::Meta::Class::Trait::$trait_name"(在“阶级背景”调用时)来实现,而不仅仅是传回一个较短的名字。

+0

请参阅我的修改我的问题,我试图添加更多的细节。 – Danny 2009-07-07 19:47:16