Impossible d'affecter une instruction if à une variable
Le problème ici est que je ne comprends pas bien la différence entre les instructions et les blocs dans le flux de contrôle.
En regardant l'opérateur ternaire, je peux l'utiliser pour attribuer une variable. Mais c'est un opérateur, donc c'est comme appliquer une fonction - n'est-ce pas?
> my $variable = True ?? 34 !! 42;
34
puisque dans la documentation raku dit:
if Documentation
ifPour exécuter conditionnellement un bloc de code, utilisez un
ifsuivi d'une condition. La condition, une expression, sera évaluée immédiatement après l'instruction avant laiffin. Le bloc attaché à la condition ne sera évalué que si la condition signifieTruelorsqu'elle est forcée à Bool. Contrairement à certaines langues, la condition ne doit pas être mise entre parenthèses, à la place le{et}autour du bloc sont obligatoires:
do Documentation
doLe moyen le plus simple d'exécuter un bloc là où il ne peut pas être une instruction autonome consiste à écrire
doavant:
donc cela devrait fonctionner dans les deux cas:
> my $variable = do {34};
34
> my $variable = if True {34;} else {43;} ===SORRY!=== Word 'if' interpreted as a listop; please use 'do if' to introduce the statement control word ------> my $variable = if⏏ True {34;} else {43;}
Unexpected block in infix position (two terms in a row)
------> my $variable = if True⏏ {34;} else {43;}
comme indiqué dans l'erreur, je dois ajouter le do:
> my $variable = do if True {34;} else {43;}
34
Donc, le ifbloc ne fonctionne vraiment pas ... ou quel est le vrai problème ici?
Réponses
TL; DR: la différence réelle se situe entre l' instruction et l' expression , et non entre l' instruction et le bloc . doest un préfixe d'instruction qui crée des expressions.
ifcrée en fait une instruction (tout ce qui est exécuté dans Raku l'est), cependant, ce n'est pas une expression . doest un préfixe d'instruction, et il transforme les instructions en expressions.
Cependant, ce ifn'est pas vraiment une fonction de première classe que vous pouvez attribuer à une variable ou gérer autour. Chaque fois que vous trouvez des morceaux de syntaxe comme celui-là (ou for, par exemple), vous devez les préfixer avec dopour les «exprimer».
say &say.^name;# OUTPUT: «Sub» say &do.^name; # OUTPUT: «===SORRY!=== Error while compiling <tmp>Undeclared routine:...
say &if.^name; # OUTPUT: «===SORRY!=== Error while compiling <tmp>Undeclared routine: if used at line 1»
Donc if, par lui-même, ne crée pas de bloc, il ne crée pas d'expression, il crée simplement une instruction. Vous devez le faire précéder de dosi vous voulez qu'il le transforme réellement en expression. Il fait courir le bloc qui est derrière elle, cependant.
Revenons à la question initiale, aux déclarations et aux blocages. Les blocs sont des objets, des citoyens de première classe. Vous pouvez les utiliser, les appliquer, les faire circuler.
my &ifs = { if $_ {34} else {43}};
ifs(True).say; # OUTPUT: «34»
Les instructions sont des blocs jetables que vous exécutez simplement. Dans certains cas, ce sont aussi des expressions: elles donnent un résultat que vous pouvez ensuite attribuer.
my &ifs = { if $_ {34} else {43}};
my $result = ifs(True).say; # OUTPUT: «34» say $result; # OUTPUT: «True»
L' ifs(True).sayinstruction s'imprime en sortie, elle produit également un résultat qui peut être affecté. Les trois lignes sont également des déclarations et, en fait, des expressions aussi.
Cependant, certaines structures de contrôle ne créent pas d'expressions.
Certains autres le font;
forcrée une expression;whilene fait pas.
ifen est un exemple. Ils ne produisent pas de résultat. Vous les utilisez pour les effets secondaires: exécuter une instruction (si elle est vraie) ou une autre (si non). Vous pouvez les transformer en bloc, comme ci-dessus, et les faire circuler. Ou vous pouvez simplement les faire précéder doet leur faire produire un résultat jetable, que vous pouvez ensuite utiliser.
Cela dépendra donc beaucoup de votre cas d'utilisation réel. Vous pouvez entourer l'instruction if avec des accolades et créer un bloc; ou vous pouvez simplement utiliser le résultat en créant une expression. Ou vous voudrez peut-être l'utiliser uniquement pour les effets secondaires, sans rien faire.