cod*_*ons 7 metaprogramming object rakudo meta-object-protocol raku
2011 年优秀的 Raku Advent of Raku 后元编程:什么、为什么和如何提供了一些使用EXPORTHOW
创建行为类似的声明器的清晰示例class
。这是第一个:
my class SingleInheritanceClassHOW
is Metamodel::ClassHOW
{
method add_parent(Mu $obj, Mu $parent) {
if +self.parents($obj, :local) > 0 {
die "Multiple inheritance is forbidden!";
}
callsame;
}
}
my module EXPORTHOW { }
EXPORTHOW.WHO.<class> = SingleInheritanceClassHOW;
Run Code Online (Sandbox Code Playgroud)
有没有办法对声明器执行类似的操作sub
(即允许用户提供签名和块,而不是允许用户提供属性和方法)?a 的元类Sub
是ClassHOW
,所以看起来类似的东西应该是可能的,但我没有看到这样做的方法。
该EXPORTHOW
机制仅用于覆盖将用于包声明符的元类,并进行轻微扩展,EXPORTHOW::DECLARE
还执行引入新包声明符的语法调整。
虽然可以调用.HOW
a Sub
,但结果与子例程本身无关,而是与Sub
类型的元类相关,子例程是该类型的一个实例。
确实,EXPORTHOW
这是一种“简单的事情简单”的机制(在某种程度上,将与元编程相关的任何东西称为简单是公平的!)它也是一个简单的提供:包声明的解析已经非常规则,并且编译器已经维护一个从包关键字到元类的映射表,因此为模块提供一种替换该表中的条目(或为DECLARE
)添加新条目的方法只需几个小时的编译器黑客攻击。
例程的规律性要低得多,即使这只是在语法上有些明显。虽然包几乎解析关键字(class
、role
、grammar
等),并且接下来的语法和语义对于所有这些都非常相同(允许签名的模角色),但每个sub
、method
、macro
和背后都有单独的解析规则和语义rule
。它们与整个编译过程的交互也更加复杂。RakuAST 正在进行的工作正在为这种混乱带来更多秩序,最终 - 当与俚语结合时 - 将提供一种引入新的sub
类似结构并赋予它们语义的方法。