Створення користувацького декларатора


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 сам в кінцевому підсумку використовуватиме власний декларатор, він може піти кудись ще і його не потрібно витягувати в окремий Тип). Як би я пішов робити це?


Я розумію, що це в основному запитання "Як мені ЯК?" але я не бачив жодних реальних записів, і існуючі модулі, які його використовують (Red / Cro), є досить складними (якщо красивими) звірами, які важко прослідкувати з першого погляду.
користувач0721090601

Схоже, ви хочете повторно використовувати підписи, правда?
jjmerelo

2
jjmerelo: ні, насправді кінцевою метою є створення підкласу методу (реєстрація його в класі, якщо він використовується всередині нього) та використання абсолютно іншої мови всередині кодового блоку (у такому випадку
подібний до регулярних виразів

2
jjmerelo: див . пропозицію gist.github.com/alabamenhu/2fec7a8f51a24091dc1b104a2ae2f04d . Мені кілька днів від тестового модуля для показу, але я працюю в більшості логістики Binex, але для синтаксису,
схожого

Відповіді:


5

-1. Обмеження (лише для пакетів)

Метод EXPORTHOW викликає .set_how за поточним $?LANGдодаванням сленгу до останнього.
Потім він add_package_declarator до MAIN $?LANGякого додає package_declaratorметод до своїх дій та граматики. Це, я думаю, єдиний "динамічний сленг" (у World.nqp).

Якщо ви хочете, це перезаписати rutral_declarator . Тоді ви повинні написати сленг, що імітує щойно цитований ланцюг. Якщо ви погоджуєтесь зберегти ключове слово методу та зробити автоматичний підпис у класі, скажімо, відповідно до назви методу, ось такий спосіб:

Примітка: Пакет - це контейнер (пакет, граматика, модуль, роль, ноу-хау, перерахунок, клас, підмножина). Якщо ви помістите код всередину, як метод, він виконується (я просто спробував):

0. Опис (ЕКСПОРТ)

Я б використав незадокументований EXPORTHOW та DECLAREв модулі, тому що не знайшов способу з Phaser . Мабуть, вже пізно навіть у BEGIN.

Я наводжу приклад - це декорування кожного методу в класі (навіть 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. Джерела


Відмінно. Простий і простий. Дякую!
користувач0721090601
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.