Faire un déclarant personnalisé


9

Disons que j'utilise un certain ensemble de passe-partout assez régulièrement:

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

}

Je préfère pouvoir simplement dire:

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

Et quelque part dans Bar, configurez la déclaration pour bar (ou, puisque la classe Foo utilisera elle-même finalement son propre déclarant, elle pourrait aller ailleurs et n'a pas besoin d'être extraite dans un type séparé). Comment pourrais-je procéder?


Je comprends que cela demande essentiellement "Comment puis-je COMMENT?" mais je n'ai vu aucune véritable écriture, et les modules existants qui l'utilisent (Red / Cro) sont des bêtes assez complexes (si belles) qui sont difficiles à suivre en un coup d'œil.
user0721090601

Il semble que vous souhaitiez réutiliser les signatures, non?
jjmerelo

2
jjmerelo: non, le but ultime est de faire une sous-classe de méthode (en l'enregistrant avec la classe si elle est utilisée à l'intérieur) et en utilisant un langage entièrement différent à l'intérieur du bloc de code (un style regex, dans ce cas)
user0721090601

2
jjmerelo: voir gist.github.com/alabamenhu/2fec7a8f51a24091dc1b104a2ae2f04d pour la proposition. Je ne suis qu'à quelques jours d'avoir un module de test à montrer, mais j'ai la majeure partie de la logistique du Binex, mais pour la syntaxe Raku
user0721090601

Réponses:


5

-1. Limitations (uniquement pour les packages)

La méthode EXPORTHOW appelle .set_how sur le courant en $?LANGajoutant un argot à ce dernier.
Ensuite, il ajoute add_package_declarator au MAIN $?LANGqui ajoute une package_declaratorméthode à ses actions et à sa grammaire. C'est, je pense, le seul "argot dynamique" (dans World.nqp).

Si vous voulez écraser routine_declarator . Ensuite, vous devez écrire un argot imitant la chaîne que je viens de citer. Si vous acceptez de conserver le mot-clé method et de faire la signature automatique dans la classe, disons selon le nom de la méthode, voici un moyen:

Remarque: Un package est un conteneur (package, grammaire, module, rôle, savoir-faire, énumération, classe, sous-ensemble). Si vous mettez du code à l'intérieur comme une méthode, cela s'exécute (je viens de l'essayer):

0. Description (EXPORTATION)

J'utiliserais EXPORTHOW non documenté et DECLAREdans un module car je n'ai pas trouvé de moyen avec Phaser . Apparemment, il est trop tard, même à BEGIN.

L'exemple que je donne est de décorer chaque méthode d'une classe (même 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. Exécutable

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. Sortie

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

4. Sources


Excellent. Simple et direct. Merci!
user0721090601
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.