J'essaie de créer un trait d'attribut. Le cas d'utilisation consiste à marquer certains attributs d'une classe comme "crudable" dans le contexte d'un mappage objects-to-documents alors que d'autres ne le sont pas.Perl 6 - Est-il possible de créer un trait d'attribut qui définit un méta-attribut?
role crud {
has Bool $.crud is default(True);
}
multi trait_mod:<is>(Attribute $a, crud, $arg) {
$a.container.VAR does crud($arg);
}
class Foo {
has $.bar is rw;
# Provide an extra nested information
has $.baz is rw is crud(True);
}
En lisant et en adaptant some example code, je réussi à obtenir quelque chose qui semble faire ce que je veux. Voici a snippet with test case.
Quand j'instancier un nouveau Foo
objet et définissez l'attribut $.bar
(qui is
pas crud
), ça ressemble à ça:
.Foo @0
├ $.bar is rw = 123456789
└ $.baz is rw = .Scalar+{crud} @1
└ $.crud +{crud} = True
Ce que je comprends est que l'attribut $.baz
a ce que j'appelle meta-attribut qui est indépendant de sa valeur potentielle.
Cela me semble bon (si j'ai bien compris ce que j'ai fait ici et que mes traits ne sont pas un hack sale). Il est possible d'atteindre $foo.baz.crud
, soit True
. Cependant, je ne comprends pas très bien ce que veut dire , et si je peux y mettre quelque chose et comment.
Lorsque je tente de définir l'attribut $.baz
instance, cette erreur est renvoyée:
Cannot modify an immutable Scalar+{crud} (Scalar+{crud}.new(crud => Bool::True))
in block <unit> at t/08-attribute-trait.t line 30
Note: Ceci est la chose la plus proche à une solution de travail que je réussi à obtenir. Je n'ai pas besoin de paramètres de crud différents pour différentes instances de classes Foo instanciées.
Je ne veux jamais changer la valeur du booléen, en fait, une fois l'objet instancié, juste fournissant aux attributs avec is crud
. Je ne suis même pas intéressé de passer une valeur True
ou False
comme argument: s'il serait possible de simplement définir l'attribut de trait booléen à True
par défaut, cela suffirait. Je ne l'ai pas réussi à le faire si, comme:
multi trait_mod:<is>(Attribute $a, :$crud!) {
# Something like this
$a.container.VAR does set-crud;
}
class Foo {
has $.bar is rw;
has $.baz is rw is crud;
}
Suis-je essayer de faire quelque chose d'impossible? Comment pourrais-je adapter ce code pour réaliser ce cas d'utilisation?
Pourriez-vous expliquer ce que 'fait crud ($ arg)' fait étant donné que 'crud' ne prend pas d'arguments? Ou, étant donné que cela ressemble à un faux code et que vous dites que ce n'est pas pertinent pour votre attention dans cette question de toute façon, éditez-le? En d'autres termes, faites du dernier bit du code le cœur de la question et jetez le premier morceau de code. Cela a-t-il du sens? – raiph
Oh!Étant donné la version simplifiée de la question (en ignorant '$ arg'), il me semble soudain que vous essayez simplement de faire ce' role crud {}; classe Foo {a $ .baz est rw est crud}; dis Foo.new.baz ~~ crud; # True' devrait faire au lieu de ce qu'il fait actuellement, à savoir se plaindre que "est un trait sur la variable $ -sigil pas encore implémenté. Suis-je à des kilomètres ou ...? – raiph
Et si je ne suis pas à des kilomètres, qu'en est-il de la fonction de 'role crud {}; classe Foo {has @ .baz est rw est crud}; dis Foo.new.baz ~~ crud; # True, c'est-à-dire utiliser un tableau au lieu d'un scalaire? – raiph