如何获取Perl 6类型的所有角色及判断类型是类还是角色
嘿,这两个Perl 6的问题我熟,给你详细说说~
获取类型的所有角色列表
首先,Perl 6的类型对象自带了.roles方法,能直接返回该类型直接声明消耗的角色。举个例子:
role R1 {} role R2 {} class C does R1 {} class D is C does R2 {} say D.roles; # 输出 (R2)
但如果想拿到整个继承体系里所有被消耗的角色(包括父类、父角色传递过来的),可以结合.^mro遍历整个方法解析顺序,把每个类型的角色都收集起来再去重:
my @all-roles = D.^mro.flatmap(*.roles).unique; say @all-roles; # 输出 (R1 R2)
顺带提一句,你之前用的.does方法其实本身就会检查整个继承链的角色,比如D.does(R1)会返回True,不用自己遍历MRO去判断单个角色是否存在。
判断类型是类还是角色
要严谨区分一个类型是类还是角色,最靠谱的方式是检查它的元模型类型。Perl 6里,类的元类型是Perl6::Metamodel::ClassHOW,角色的元类型是Perl6::Metamodel::RoleHOW,用.^isa方法就能判断:
sub is-role($type) { $type.^isa(Perl6::Metamodel::RoleHOW) } sub is-class($type) { $type.^isa(Perl6::Metamodel::ClassHOW) } # 测试示例 role R {} class C {} say is-role(R); # 输出 True say is-class(C); # 输出 True say is-role(C); # 输出 False
还有个小技巧可以快速区分:角色的类型对象是非确定的,调用.DEFINITE属性会返回False;而类的类型对象是确定的,.DEFINITE返回True。不过要注意,抽象类的.DEFINITE依然是True(抽象类只是不能实例化,但类型对象是确定的),所以这个方法适合快速判断普通类和角色:
say R.DEFINITE; # 输出 False(角色) say C.DEFINITE; # 输出 True(类)
内容的提问来源于stack exchange,提问作者brian d foy
相关产品推荐
相关产品推荐

