Comment les énumérations sont-elles augmentables?
Dans Raku, les HOW doivent exposer une liste d' archétypes via une archetypesméthode, qui est utilisée pour déterminer quelles fonctionnalités plus larges des types un type implémente, par exemple la paramétrie ou la composabilité. J'ai remarqué que Metamodel::EnumHOW(le HOW utilisé avec les enums) a l' augmentablearchétype, qui est donné aux types qui peuvent être étendus après la composition avec le augmentmot - clé lorsque le MONKEY-TYPINGpragma est activé.
Ma première estimation de la raison pour laquelle les énumérations seraient augmentables serait de permettre l'ajout de valeurs enum, j'ai donc essayé d'écrire ceci:
use v6;
use MONKEY-TYPING;
enum Foo <foo bar baz>;
augment enum Foo <qux>;
say qux;
Mais cela jette:
bastille% raku test.raku
===SORRY!=== Error while compiling /home/morfent/test.raku
Redeclaration of symbol 'Foo'.
at /home/morfent/test.raku:5
------> augment enum Foo⏏ <qux>;
Ils ne sont donc probablement pas destinés à être augmentés de cette manière.
Ma prochaine hypothèse était qu'ils étaient destinés à être augmentables en ce qui concerne les valeurs enum, pas le type enum lui-même. augment, fait intéressant, ne prend pas en compte le COMMENT a réellement un type lorsque vous lui dites quel type de type vous augmentez, alors j'ai essayé d'augmenter une énumération comme vous le feriez avec une classe:
use v6;
use MONKEY-TYPING;
enum Foo <foo bar baz>;
augment class Foo {
proto method is-foo(::?CLASS:D: --> Bool:D) {*}
multi method is-foo(foo: --> True) { }
multi method is-foo(::?CLASS:D: --> False) { }
}
say foo.is-foo;
Ce qui fonctionne:
bastille% raku test.raku
True
Mais cela ne ressemble pas à la façon dont vous êtes censé augmenter les énumérations pour moi. Cette utilisation de augmentest plutôt étrange, et rien n'implique que cela devrait être possible à partir de sa documentation. Comment comptez-vous augmenter les énumérations?
FAQ
Foo.is-foone semble pas avoir de code? Qu'est-ce que ça fait?
is-fooest plutôt sévère quant à la façon dont il utilise les fonctionnalités des signatures et des paramètres. Cela dépend de ce qui suit:
- Les valeurs constantes peuvent être utilisées comme des types dans les signatures. Cela inclut les valeurs d'énumération, qui sont traitées au moment de la compilation.
- Une routine peut être amenée à toujours renvoyer une valeur constante en définissant le type de valeur de retour de sa signature.
- Les variables pour tout paramètre donné dans une signature sont facultatives.
- Lorsqu'un deux-points est placé après le premier paramètre comme celui-ci, ce premier paramètre est l' appelant de la signature . Dans le cas des méthodes, cela vous permet de taper
selfcomme vous le souhaitez. ::?CLASSest un alias pour la classe dans laquelle une méthode est déclarée. Cela existe dans les corps de classe et de rôle, donc bien queFoon'étant pas vraiment une classe, c'est ce à quoi le symbole fait référence.:Dest un smiley de type indiquant qu'un type ne doit vérifier le type que par rapport à ses propres instances, et non par des objets de type vérifiant comme lui.
Puisqu'il foos'agit d'un type plus spécifique que ::?CLASS:D(un alias pour Foo:D), lors de l'appel de cette méthode foo, le foomulti sera sélectionné et Truesera retourné, mais dans tous les autres cas, le ::?CLASS:Dmulti sera sélectionné et Falsesera retourné.
Réponses
En Java, vous pouvez ajouter des attributs et des fonctions presque arbitraires aux énumérations. Donc, je pense que l'augmentation de la façon dont vous décrivez pourrait avoir du sens. Par example:
use MONKEY-TYPING;
enum Days(Monday => 1, Tuesday => 2, Wednesday => 3, Thursday => 4, Friday => 5, Saturday => 6, Sunday => 7);
augment class Days {
proto method is-weekend(::?CLASS:D: --> Bool:D) {*}
multi method is-weekend(Saturday: --> True) { }
multi method is-weekend(Sunday: --> True) {}
multi method is-weekend(::?CLASS:D: --> False) { }
proto method days-til-weekend(::?CLASS:D: --> Int:D) {*}
# there is probably a better way to express this, but
# hopefully the concept is clear
multi method days-til-weekend(Monday: --> 4) {}
...
}
say Monday.is-weekend;
say Wednesday.days-til-weekend;
say Saturday.is-weekend;