7 votes

perl6/raku : comment restreindre les valeurs autorisées dans une variable ?

Perl6/Raku

J'aimerais créer un sous-domaine auquel seules certaines valeurs sont autorisées à être transmises. Et ne pas passer la valeur autorisée créera une erreur de vérification (perl6 -c).

Comment dois-je m'y prendre ?

Merci beaucoup, -T

Bonjour Raiph,

Dans mon module WinPopUps, j'ai utilisé la méthode "where" car elle indique à l'utilisateur, d'un seul coup d'œil, quelles sont les valeurs autorisées. J'adore ça ! C'est une question de maintenabilité ! (Au fait, ce qui suit est le monstre que vous avez créé !)

sub WinPopUp( Str $TitleStr, 
              Str $MessageStr,
              Str $Icons where   * ~~ "Exclamation"             |
                                      "Warning"                 |
                                      "Information"             |
                                      "Asterisk"                |
                                      "Question"                |
                                      "Stop"                    |
                                      "Error"                   |
                                      "Hand",
              Str $Buttons where * ~~ "AbortRetryIgnore"        | 
                                      "CancelTryAgainContinue"  |
                                      "Help"                    |
                                      "Ok"                      |
                                      "OkCancel"                |
                                      "RetryCancel"             |
                                      "YesNo"                   |
                                      "YesNoCancel" ) 
              is export( :WinPopUp ) {

Merci pour votre aide ! -T

Faites-moi savoir si vous voulez le module complet et où le poster.

11voto

Holli Points 990

Vous pouvez simplement ajouter un where condition sur les valeurs

sub foo( Int $binary where * ~~ 0|1 ) { ... }

En where La condition peut être un bloc de code arbitraire (ou même un sous, je crois).

Si vous avez besoin de la condition plusieurs fois, vous pouvez créer une subset .

subset BinaryInt of Int where * ~~ 0|1;

et l'utiliser ensuite dans la signature

sub foo( BinaryInt $binary ) { ... }

Notez que cela ne se limite pas aux signatures de sous-routines. Les contraintes/conditions sont appliquées partout

my BinaryInt $i = 0; 
$i++; 
$i++;
# -> Type check failed in assignment to $i; expected BinaryInt but got Int (2)

Vous pouvez également avoir des sous-ensembles de sous-ensembles :

subset FalseBinaryInt of BinaryInt where not *;
my FalseBinaryInt $i = 0; 
$i++; 
# -> Type check failed in assignment to $i; expected FalseBinaryInt but got Int (1)

Edit : JJ en bas a raison. Dans ce cas, une énumération est utile. Voici

sub WinPopUp( Str $TitleStr, 
              Str $MessageStr,
              MessageBoxIcons $Icons where   * ~~ Exclamation |
                                                  Information |
              ...

Associé à une énumération comme

enum MessageBoxIcons is export {
    Exclamation => 0x00000030,
    Information => 0x00000040,
    ...
}

vous protège des fautes de frappe aléatoires, car les membres d'un enum sont des symboles, et si vous en épellez mal un, le compilateur le détectera. De plus, vous n'avez pas besoin de chercher les valeurs à introduire dans le fichier MessageBoxW (c'est ce que vous faites, je suppose).

En parlant de MessageBoxW j'appellerais votre sous-marin message-box (dans Raku, nous avons tendance à utiliser la casse Camel uniquement pour les classes, les types et autres), juste pour rester cohérent avec MessageBoxW

0voto

jjmerelo Points 173

Dans votre cas, le mieux serait probablement d'utiliser enum s :

enum Icons <Exclamation Warning Information>;
sub pop-up( Icons $icon ) { $icon}; 
say pop-up( Information ); # OUTPUT: «Information»

Cependant, vous utilisez Str déjà pour une raison quelconque, il serait donc préférable d'utiliser sous-ensembles :

subset Icons of Str where * eq any <Exclamation Warning Information>;
sub pop-up( Icons $icon ) { $icon};
say pop-up( "Information" ); 

Ceux-ci ont déjà été mentionnés dans La réponse de Holli mais seulement "si vous allez les utiliser plusieurs fois". Je définirais un sous-ensemble même si vous ne l'utilisez qu'une seule fois. C'est plus sûr, et aussi plus clair, ainsi que testable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X