perl - UNIVERSAL 中“角色”的定义是什么?Perl 角色如何工作?
问题描述
Perl 有一个名为的内部伪模块UNIVERSAL
,所有模块都从该模块继承。它有一个名为 的方法DOES
,从docs on 开始UNIVERSAL
。
$obj->DOES( ROLE )
CLASS->DOES( ROLE )
DOES
检查对象或类是否执行角色ROLE
。角色是一组命名的特定行为(通常是特定名称和签名的方法),类似于一个类,但它本身不一定是一个完整的类。例如,日志记录或序列化可能是角色。
DOES
并且isa
相似,如果其中任何一个为真,您就知道调用该方法的对象或类可以执行特定的行为。然而,DOES
它的不同之处isa
在于它不关心 invocand 如何执行操作,只关心它。(isa
当然要求继承关系。其他关系包括聚合、委托和模拟。)角色和类之间存在关系,因为每个类都意味着存在同名角色。继承和角色之间也存在关系,从祖先类继承的子类隐式地执行其父类执行的任何角色。因此,您可以安全地使用
DOES
代替isa
,因为它将在所有将返回 true 的地方isa
返回 true(前提是任何重写DOES
和isa
方法行为适当)。
我知道 Moose 等人提供了一个DOES
,并且我了解它是如何使用的。但从某种意义上说,a 是UNIVERSAL::DOES
什么ROLE
?他们是如何被追踪的?除了 Moose 之外,它们是如何被创造出来的DOES
呢?我尝试查看源代码,但未提供的实现DOES
。这是perl中的ROLE
东西的概念吗?CORE
这似乎与(also / )perldoc perlapi
的提及有关sv_does_sv
sv_does
sv_does_pv
sv_does_sv
返回一个boolean
指示是否SV
执行特定的命名角色。SV
可以是 Perl 对象或 Perl 类的名称。
bool sv_does_sv(SV* sv, SV* namesv, U32 flags)
我可以sv_does_sv
在. universal.c
SV 角色的定义是什么?我在哪里可以找到有关此的更多信息?
从用户层面来看,这里的代码是做什么的,(这是一个子引用)
UNIVERSAL->can('DOES')
返回的地址UNIVERSAL->can('isa')
与同一次调用中的地址不同,所以它做的事情不同,我可以在上面的链接中看到那个垃圾universal.c
。
解决方案
UNIVERSAL::DOES
相当于:
sub DOES {
croak "Usage: invocant->DOES(kind)"
if @_ != 2;
$_[0]->isa($_[1]);
}
在内部,在传递的第一个 SV 上sv_does_sv
调用该方法。isa
perl 本身不提供角色的实现,因此留给角色模块来DOES
为它们提供解释。
Moose、Moo、Role::Tiny、Mouse 等中的约定是,该DOES
方法对于类及其父类以及类及其父类组成的角色都是正确的。这些库还提供了does
方法,该方法仅适用于类及其父类的组合角色,而不适用于类或其父类。
推荐阅读
- reporting-services - 我们可以在 SSRS 电子邮件订阅页面中禁用“包含报告”选项吗?
- php - 当我尝试从数据库中获取并显示逗号分隔值时,Explode 正在显示数组
- javascript - Firebase 和 JavaScript:从实时数据库更新网站上获取的数据,而无需重新加载网站
- ruby - 在对象初始化时在 ruby 中动态构建访问器
- visual-studio-2019 - 在 Visual Studio 2019 和 dotnetbrowser 中停止活动窗格穿透并激活其后面的对象的触摸手势
- android - 如何以编程方式实现谷歌位置自动完成并获得 kotlin 的 latlng?
- autodesk-forge - 如何强制设计自动化打开分离模型?
- java - Maven为python3 ANTLR语法文件生成python代码
- javascript - 使用反应钩子更改图像和描述 onClick 的最佳方法
- javascript - 使用 React 显示对象详细信息