Criando um declarador personalizado

9

Digamos que eu use um certo conjunto de clichês regularmente:

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;
    …
  }

}

Prefiro dizer:

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

E em algum lugar em Bar, configure a declaração para bar (ou, como a própria classe Foo finalmente usará seu próprio declarador, ele poderá ir para outro lugar e não precisará ser extraído em um tipo separado). Como eu faria isso?

user0721090601
fonte
Eu entendo que isso é basicamente perguntando "Como eu COMO?" mas eu não vi nenhum artigo real, e os módulos existentes que o usam (Vermelho / Cro) são bestas bastante complexas (se bonitas) que são difíceis de acompanhar de relance.
user0721090601 6/04
Parece que você deseja reutilizar assinaturas, certo?
jjmerelo 7/04
2
jjmerelo: não, objetivo, na verdade final é fazer uma subclasse método (registrá-lo com a classe se usado dentro dela) e usando uma linguagem totalmente diferente dentro do bloco de código (a regex-como um, neste caso)
user0721090601
2
jjmerelo: consulte a proposta em gist.github.com/alabamenhu/2fec7a8f51a24091dc1b104a2ae2f04d . Estou a poucos dias de ter um módulo de teste para mostrar, mas tenho a maior parte da logística do Binex funcionando, mas para a sintaxe semelhante ao Raku
user0721090601 07/04

Respostas:

5

-1. Limitações (apenas para pacotes)

O método EXPORTHOW chama .set_how na atual $?LANGadicionando uma gíria à última.
Em seguida, adicione add_package_declarator ao MAIN $?LANGqual adiciona um package_declaratormétodo às suas ações e gramática. Acho que é a única "gíria dinâmica" (no World.nqp).

Se o que você deseja é substituir o rotina_declarador . Então você tem que escrever uma gíria que imita a corrente citada. Se você aceitar manter a palavra-chave method e criar a assinatura automática na classe, digamos de acordo com o nome do método, aqui está uma maneira:

Nota: Um pacote é um contêiner (pacote, gramática, módulo, função, know-how, enum, classe, subconjunto). Se você colocar o código dentro como um método, isso é executado (eu apenas tentei):

0. Descrição (EXPORTHOW)

Eu usaria EXPORTHOW não documentado e DECLAREem um módulo porque não encontrei um caminho com a Phaser . Aparentemente, é tarde demais, mesmo no início.

O exemplo que dou é decorar todos os métodos de uma classe (par 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. Executável

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. Saída

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

4. Fontes

Tinmarino
fonte
Excelente. Simples e direto. Obrigado!
user0721090601 10/04