Создание собственного декларатора

9

Допустим, я использую определенный набор шаблонов довольно регулярно:

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 (или, поскольку класс Foo сам в конечном итоге будет использовать свой собственный декларатор, он может пойти куда-нибудь еще и его не нужно извлекать в отдельный тип). Как бы я поступил так?

user0721090601
источник
Я понял, что это в основном вопрос "Как мне КАК?" но я не видел никаких реальных рецензий, и существующие модули, которые его используют (Red / Cro), являются довольно сложными (если красивыми) зверями, за которыми сложно следить с первого взгляда.
user0721090601
Похоже, вы хотите повторно использовать подписи, верно?
jjmerelo
2
jjmerelo: нет, на самом деле конечной целью является создание подкласса метода (регистрация его с классом, если он используется внутри него) и использование совершенно другого языка внутри блока кода (в данном случае подобного регулярному выражению)
user0721090601
2
jjmerelo: см. предложение gist.github.com/alabamenhu/2fec7a8f51a24091dc1b104a2ae2f04d . У меня есть несколько дней, чтобы показать тестовый модуль, но у меня есть большая часть материально-технического обеспечения работы Binex, но для Raku-подобного синтаксиса
user0721090601

Ответы:

5

-1. Ограничения (только для пакетов)

Метод EXPORTHOW вызывает .set_how для текущего $?LANGдобавления сленга к последнему.
Тогда add_package_declarator к MAIN $?LANGкоторой добавляется package_declaratorметод его действий и грамматике. Я думаю, это единственный «динамический сленг» (в World.nqp).

Если вы хотите перезаписать рутинный_декларатор . Затем вы должны написать сленг, имитирующий только что процитированную цепочку. Если вы согласны сохранить ключевое слово метода и сделать автоматическую подпись в классе, скажем, в соответствии с именем метода, вот способ:

Примечание. Пакет - это контейнер (пакет, грамматика, модуль, роль, ноу-хау, перечисление, класс, подмножество). Если вы поместите код внутри как метод, он будет выполнен (я только что попробовал):

0. Описание (EXPORTHOW)

Я бы использовал недокументированный EXPORTHOW и DECLAREв модуле, потому что я не нашел пути к Phaser . Видимо, уже поздно, даже в НАЧАЛЕ.

Пример, который я привожу, украшает каждый метод в классе (даже BUILDALL).

1. Lib ( 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. Источники

Tinmarino
источник
Отлично. Просто и понятно. Спасибо!
user0721090601