"ROLE" 在 UNIVERSAL 中的定义是什么?Perl 角色是如何工作的?

What is the definition of "ROLE" in UNIVERSAL and how do Perl Roles work?

Perl 有一个名为 UNIVERSAL 的内部伪模块,所有模块都继承自该伪模块。它有一个名为 DOES 的方法,来自 the docs on UNIVERSAL.

$obj->DOES( ROLE )

CLASS->DOES( ROLE )

DOES checks if the object or class performs the role ROLE. A role is a named group of specific behavior (often methods of particular names and signatures), similar to a class, but not necessarily a complete class by itself. For example, logging or serialization may be roles.

DOES and isa are similar, in that if either is true, you know that the object or class on which you call the method can perform specific behavior. However, DOES is different from isa in that it does not care how the invocand performs the operations, merely that it does. (isa of course mandates an inheritance relationship. Other relationships include aggregation, delegation, and mocking.)

There is a relationship between roles and classes, as each class implies the existence of a role of the same name. There is also a relationship between inheritance and roles, in that a subclass that inherits from an ancestor class implicitly performs any roles its parent performs. Thus you can use DOES in place of isa safely, as it will return true in all places where isa will return true (provided that any overridden DOES and isa methods behave appropriately).

我知道 Moose 等人提供了一个 DOES,我知道它是如何使用的。 但是在 UNIVERSAL::DOES 的意义上什么是 ROLE?他们是如何被追踪的?除了 Moose 之外,它们是如何被创造出来的 来满足 DOES 的?我试着查看源代码,但是 the implementation of DOES was not provided. Is this notion of a ROLE something in CORE perl? This seems to be related to the perldoc perlapi's mention of sv_does_sv (also sv_does/sv_does_pv)

sv_does_sv Returns a boolean indicating whether the SV performs a specific, named role. The SV can be a Perl object or the name of a Perl class.

bool sv_does_sv(SV* sv, SV* namesv, U32 flags)

我可以在 implementation of universal.c 中看到对 sv_does_sv 的调用。 SV 角色的定义是什么?我在哪里可以找到有关此的更多信息?

从用户层面来看,这里的代码是做什么的,(这是一个subref)

UNIVERSAL->can('DOES')

返回的地址与同一调用中的 UNIVERSAL->can('isa') 不同,所以它做的事情不同,我可以在上面链接的 universal.c.

中看到那个垃圾

UNIVERSAL::DOES相当于:

sub DOES {
   croak "Usage: invocant->DOES(kind)"
       if @_ != 2;
   $_[0]->isa($_[1]);
}

在内部,sv_does_sv 在传递的第一个 SV 上调用 isa 方法。 perl 本身不提供角色的实现,因此留给角色模块提供一个 DOES 来说明它们。

Moose、Moo、Role::Tiny、Mouse 等的约定是 DOES 方法对 class 及其父 classes 是正确的,并且class 及其父 classes 组成的角色。这些库还提供了 does 方法,该方法仅适用于 class 及其父 classes 的组合角色,但不适用于 class 或其父 [=24] =]es.