驼鹿的角色和特征有何不同?

发布于 2024-07-26 03:29:22 字数 1455 浏览 2 评论 0原文

我编写了一组在 Moose< 中实现的类和接口/a> 也使用角色。 我无法理解的是 Moose 特征与角色在使用和实现方面的确切差异。

Moose 文档状态:

重要的是要了解角色和特质是同一回事。 角色可以用作特质,特质就是角色。 两者的唯一区别是特征的打包方式让 Moose 将短名称解析为类名。 换句话说,对于一个特征,调用者可以通过像“Big”这样的短名称来引用它,并且 Moose 会将其解析为像 MooseX::Embiggen::Meta::Attribute::Role::Big 这样的类。< /p>

我的理解是,特质和角色是“相同的”。 然而,当使用 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

I have written a set of classes and interfaces that are implemented in Moose also using roles. What I am having trouble understanding is the exact differences in both usage and implementation of Moose traits vs. roles.

The Moose documentation states:

It is important to understand that roles and traits are the same thing. A role can be used as a trait, and a trait is a role. The only thing that distinguishes the two is that a trait is packaged in a way that lets Moose resolve a short name to a class name. In other words, with a trait, the caller can refer to it by a short name like "Big", and Moose will resolve it to a class like MooseX::Embiggen::Meta::Attribute::Role::Big.

It is my understanding that traits and roles are "the same". However, when implementing a basic test of the idea using the use Moose -traits 'Foo' syntax does not seem to do what I would expect. Surely I must be missing something here.

This first example fails with "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 -traits => 'HasTable';
__PACKAGE__->foo();  #Can't locate object method 'foo'

Compared to this one (which does work):

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冰之心 2024-08-02 03:29:22

这是 Moose 使用术语“特质”和“角色”的唯一区别。
Moose 的文档和 API 经常使用术语“特征”作为“应用的角色”
到元类”。在您修改后的答案中,您的第一个示例将角色应用于
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();

您将看到“foo at [script].line 3.”,这正是它应该做的
正在做。

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

This is the only difference in how Moose uses the terms "Trait" and "Role".
Moose's documentation and APIs often use the term "traits" as "Roles applied
to Metaclasses". In your revised answer your first example applies the Role to
MyApp::User's metaclass via -traits, the second example applies it to the
class.

If you change your first example to:

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

You'll see "foo at [script]. line 3." Which is exactly what it supposed to
be doing.

UPDATE: Apparently I'm not exactly correct here. Traits are roles applied to instances. The -traits hook applies HasTable to the metaclass instance for MyApp::User. I have updated the relevant Moose docs.

梦幻的味道 2024-08-02 03:29:22

您没有定义具有任何角色的包“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" (在“类上下文”中调用时),而不仅仅是传回较短的名称。

You don't define a package 'x::Foo' with any role. Ripped straight from the documentation, we see that register_implementation returns the name of an actually defined package:

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

The "shortcut" is achieved by Moose looking for "Moose::Meta::Class::Trait::$trait_name" (when called in a "class context"), not just passing back a shorter name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文