制作自定义声明符

Making a custom declarator

假设我经常使用某组样板文件:

class Foo {

  method abc($a: $b, $c, +@d) is pure {
    use Slang::Bar;
    …
  }

  method xyz($a: $b, $c, +@d) is pure {
    use Slang::Bar;
    …
  }

  method blarg($a: $b, $c, +@d) is pure {
    use Slang::Bar;
    …
  }

}

我只想说:

class Foo is/does Bar {
  bar  abc   { … }
  bar  xyz   { … }
  bar  blarg { … }
}

然后在 Bar 的某处,设置 bar 的声明(或者,由于 class Foo 最终将使用自己的声明符,它可以放在其他地方,而不必在单独的类型)。我该怎么做?

-1。限制(仅适用于包)

方法 EXPORTHOW calls .set_how 当前 $?LANG 为后者添加俚语。
然后它 add_package_declaratorMAIN $?LANG,后者将 package_declarator 方法添加到它的 Actions 和 Grammar。我认为,它是唯一的 "dynamic slang"(在 World.nqp 中)。

如果你想要的是覆盖routine_declarator。然后你必须写一个模仿刚才引用的链的俚语。 如果在class中接受保留方法关键字并自动签名,按照方法名说,这里有一个方法:

注意:包是一个容器(包、语法、模块、角色、专有技术、枚举、class、子集)。如果你把代码像一个方法一样放在里面,它就会被执行(我刚刚试过):

0。描述(EXPORTHOW)

我会使用未记录的 EXPORTHOW and DECLARE in a module because I did not find a way with Phaser。显然即使在开始时也为时已晚。

我给出的例子是装饰class(甚至BUILDALL)中的每个方法。

1。图书馆 (decorator.rakumod)

class DecoratedClassHOW is Metamodel::ClassHOW {
    method add_method(Mu $obj, $name, $code_obj) {
        sub wrapper ($obj, $a, $b) {
            say "Before $name";
            my $res = $code_obj($obj, $a, $b);
            say "After $name";
            return $res;
        }
        my $res = callwith($obj, $name, &wrapper);
        return $res;
    }
}

my module EXPORTHOW {
    package DECLARE {
        constant decorated = DecoratedClassHOW;
    }
}

2。可执行文件

use lib '.';
use decorator-lib;

decorated Foo {
  method abc($a, $b) {
      say "In abc: $a:$b";
  }
}

my $f = Foo.new;
$f.abc(1, 2);

3。输出

Before BUILDALL
After BUILDALL
Before abc
In abc: 1:2
After abc

4。来源