使用 EXPORTHOW 使声明符的行为类似于“sub”

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 的元类SubClassHOW,所以看起来类似的东西应该是可能的,但我没有看到这样做的方法。

Jon*_*ton 8

EXPORTHOW机制仅用于覆盖将用于包声明符的元类,并进行轻微扩展,EXPORTHOW::DECLARE还执行引入新包声明符的语法调整。

虽然可以调用.HOWa Sub,但结果与子例程本身无关,而是与Sub类型的元类相关,子例程是该类型的一个实例。

确实,EXPORTHOW这是一种“简单的事情简单”的机制(在某种程度上,将与元编程相关的任何东西称为简单是公平的!)它也是一个简单的提供:包声明的解析已经非常规则,并且编译器已经维护一个从包关键字到元类的映射表,因此为模块提供一种替换该表中的条目(或为DECLARE)添加新条目的方法只需几个小时的编译器黑客攻击。

例程的规律性要低得多,即使这只是在语法上有些明显。虽然包几乎解析关键字(classrolegrammar等),并且接下来的语法和语义对于所有这些都非常相同(允许签名的模角色),但每个submethodmacro和背后都有单独的解析规则和语义rule。它们与整个编译过程的交互也更加复杂。RakuAST 正在进行的工作正在为这种混乱带来更多秩序,最终 - 当与俚语结合时 - 将提供一种引入新的sub类似结构并赋予它们语义的方法。