Vous voudrez peut-être commencer par mon livre Learning Perl . C'est plus facile que de deviner quoi faire jusqu'à ce que vous ayez bien compris (singes, machines à écrire et Hamlet, et tout ça). :)
brian d foy
Réponses:
285
En Perl, ce qui suit est évalué à faux dans les conditions:
0'0'undef''# Empty scalar()# Empty list('')
Le reste est vrai. Il n'y a pas de mots nus pour trueou false.
@BlueWaldo: vous pouvez également utiliser cmp et <=> lors de la comparaison et de l'attribution des résultats de la comparaison à un scalaire. $ var = $ var1 cmp $ var2; 'cmp' et '<=>' (utilisés pour les comparaisons numériques) renvoient -1, 0 ou 1 si l'argument gauche est inférieur, égal ou supérieur à l'argument droit. Ce n'est pas booléen mais parfois vous voudrez peut-être savoir si un argument est égal ou inférieur ou supérieur à l'autre au lieu d'être juste égal ou non égal.
user118435
9
Problème 1: Une liste vide n'est pas fausse, car il est impossible de vérifier si une liste est vraie ou fausse. Une liste vide dans un contexte scalaire revient undef.
ikegami
4
Problème 2: ('')et ''ont la même valeur. Je pense que vous vouliez impliquer une liste avec un élément qui se compose d'une chaîne vide (même si les parens ne créent pas de listes), mais comme je l'ai déjà mentionné, il est impossible de vérifier si une liste est vraie ou fausse.
ikegami
6
Problème 3: Les objets avec un opérateur booléen surchargé peuvent également être faux.
ikegami
15
@eternicode, Perl a deux valeurs spécifiques qu'il utilise lorsqu'il doit renvoyer true et false, donc non seulement il a des booléens, il a true ( !0aka PL_sv_yes) et false ( !1aka PL_sv_no). Ou êtes-vous en train de dire que Perl devrait coasser chaque fois que quelque chose d'autre que ces deux valeurs est testé pour la vérité? Ce serait complètement affreux. Par exemple, cela empêcherait$x ||= $default;
ikegami
71
La définition la plus complète et concise de faux que j'ai rencontrée est:
Tout ce qui se transforme en chaîne vide ou en chaîne 0est faux. Tout le reste est vrai.
Par conséquent, les valeurs suivantes sont fausses:
La chaîne vide
Valeur numérique zéro
Une valeur indéfinie
Un objet avec un opérateur booléen surchargé qui évalue l'un des éléments ci-dessus.
Une variable magique qui s'évalue à l'une des précédentes lors de la récupération.
Gardez à l'esprit qu'un littéral de liste vide est évalué à une valeur indéfinie dans un contexte scalaire, il est donc évalué à quelque chose de faux.
Une note sur les "vrais zéros"
Alors que les nombres qui se stratifient en 0sont faux, les chaînes qui se chiffrent en zéro ne le sont pas nécessairement. Les seules fausses chaînes sont0 la chaîne vide. Toute autre chaîne, même si elle est de zéro, est vraie.
Les chaînes suivantes sont vraies en tant que booléen et zéro en tant que nombre:
Sans avertissement:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
Avec un avertissement:
Toute chaîne pour laquelle Scalar::Util::looks_like_numberrenvoie false. (par exemple "abc")
si je vous ai bien compris, le mot vrai dans Bien que les nombres qui se transforment en 0 sont vrais devrait être faux ou (pour éviter toute confusion) évaluer faux .
Dmitry Korolyov
1
Votre définition "concise" ne correspond pas à votre explication plus longue. Considérez: my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };. Maintenant, $valuese transforme en "XXX" mais booléen en faux.
tobyink
1
@tobyink, La version concise n'est pas parfaite, simplement la meilleure que j'ai trouvée. Il est censé être pratique et ne pas englober tout. Notez que la valeur renvoyée par votre boolne se transforme en 0. De plus, vous êtes découragé de créer des surcharges incohérentes et les valeurs que vous renvoyez peuvent être considérées comme telles. (Par exemple, un &&peut être optimisé en un ||, donc si ceux-ci n'étaient pas cohérents, vous auriez un problème.)
ikegami
Je ne sais pas si 0x00est couvert ici.
Zaid
@Zaid, voulez-vous dire la valeur renvoyée par le code 0x00(la valeur numérique zéro) ou la chaîne 0x00(pour laquelle looks_like_numberest faux)? De toute façon, c'est déjà couvert.
ikegami
59
Perl n'a pas de type booléen natif, mais vous pouvez utiliser la comparaison d'entiers ou de chaînes afin d'obtenir le même comportement. L'exemple d'Alan est une belle façon de le faire en utilisant la comparaison d'entiers. Voici un exemple
my $boolean =0;if( $boolean ){print"$boolean evaluates to true\n";} else {print"$boolean evaluates to false\n";}
Une chose que j'ai faite dans certains de mes programmes est d'ajouter le même comportement en utilisant une constante:
Les lignes marquées "use constant" définissent une constante nommée true qui évalue toujours à 1 et une constante nommée false qui évalue toujours par 0. En raison de la façon dont les constantes sont définies en Perl, les lignes de code suivantes échouent également:
true =0;
true = false;
Le message d'erreur doit dire quelque chose comme «Impossible de modifier la constante dans l'affectation scalaire».
Je l'ai vu dans l'un des commentaires que vous avez demandé sur la comparaison des chaînes. Vous devez savoir que parce que Perl combine des chaînes et des types numériques dans des variables scalaires, vous avez une syntaxe différente pour comparer les chaînes et les nombres:
my $var1 ="5.0";my $var2 ="5";print"using operator eq\n";if( $var1 eq $var2 ){print"$var1 and $var2 are equal!\n";} else {print"$var1 and $var2 are not equal!\n";}print"using operator ==\n";if( $var1 == $var2 ){print"$var1 and $var2 are equal!\n";} else {print"$var1 and $var2 are not equal!\n";}
La différence entre ces opérateurs est une source de confusion très courante en Perl.
Il est dangereux d'utiliser des constantes comme macros d'un homme pauvre de cette façon. Ces exemples de code ne sont pas équivalents: if ($exitstatus) { exit; }vs if ($exitstatus == true) { exit; }, qui pourrait ne pas être évident pour un observateur occasionnel. (Et oui, le dernier exemple est un mauvais style de programmation, mais c'est à côté du point).
Zano
16
Je recommande use boolean;. Vous devez cependant installer le module booléen depuis cpan.
En Perl, comme dans la vie, il y a beaucoup de vérités. Les inexpérimentés aiment écrire des choses idiotes comme if ($my_true_value == true). Prétendre qu'il existe une seule vraie vérité est, selon mon expérience, un chemin vers la douleur et un code inefficace.
tjd
2
Perl est philosophique par nature
ILMostro_7
13
Mes favoris ont toujours été
use constant FALSE =>1==0;use constant TRUE => not FALSE;
qui est complètement indépendant de la représentation interne.
Mauvaise réponse, mais une source solide et réputée sur perlmonks.org. Ce serait bien d'avoir du vrai contenu au lieu d'un commentaire et d'un lien. : - /
ILMostro_7
0
utilisez le préfixe de fichier suivant, cela ajoutera à votre script perl eTRUE et eFALSE, ce sera en fait REAL (!) vrai et faux (tout comme java)
#!/usr/bin/perluse strict;use warnings;use constant {#real true false, compatible with encode_json decode_json for later (we don't want field:false... will be field:0...)
eTRUE => bless(do{\(my $o =1)},'JSON::PP::Boolean'),
eFALSE => bless(do{\(my $o =0)},'JSON::PP::Boolean')};
Il y a, en fait, peu de raisons pour lesquelles vous devriez utiliser cela.
Ma raison est qu'en travaillant avec JSON, j'ai 0 et 1 comme valeurs pour les clés, mais ce hack s'assurera que les valeurs correctes sont conservées tout au long de votre script.
Réponses:
En Perl, ce qui suit est évalué à faux dans les conditions:
Le reste est vrai. Il n'y a pas de mots nus pour
true
oufalse
.la source
undef
.('')
et''
ont la même valeur. Je pense que vous vouliez impliquer une liste avec un élément qui se compose d'une chaîne vide (même si les parens ne créent pas de listes), mais comme je l'ai déjà mentionné, il est impossible de vérifier si une liste est vraie ou fausse.!0
akaPL_sv_yes
) et false (!1
akaPL_sv_no
). Ou êtes-vous en train de dire que Perl devrait coasser chaque fois que quelque chose d'autre que ces deux valeurs est testé pour la vérité? Ce serait complètement affreux. Par exemple, cela empêcherait$x ||= $default;
La définition la plus complète et concise de faux que j'ai rencontrée est:
Par conséquent, les valeurs suivantes sont fausses:
Gardez à l'esprit qu'un littéral de liste vide est évalué à une valeur indéfinie dans un contexte scalaire, il est donc évalué à quelque chose de faux.
Une note sur les "vrais zéros"
Alors que les nombres qui se stratifient en
0
sont faux, les chaînes qui se chiffrent en zéro ne le sont pas nécessairement. Les seules fausses chaînes sont0
la chaîne vide. Toute autre chaîne, même si elle est de zéro, est vraie.Les chaînes suivantes sont vraies en tant que booléen et zéro en tant que nombre:
"0.0"
"0E0"
"00"
"+0"
"-0"
" 0"
"0\n"
".0"
"0."
"0 but true"
"\t00"
"\n0e1"
"+0.e-9"
Scalar::Util::looks_like_number
renvoie false. (par exemple"abc"
)la source
my $value = do { package XXX; use overload q[""] => sub { "XXX" }, q[bool] => sub { 0 }; bless [] };
. Maintenant,$value
se transforme en "XXX" mais booléen en faux.bool
ne se transforme en0
. De plus, vous êtes découragé de créer des surcharges incohérentes et les valeurs que vous renvoyez peuvent être considérées comme telles. (Par exemple, un&&
peut être optimisé en un||
, donc si ceux-ci n'étaient pas cohérents, vous auriez un problème.)0x00
est couvert ici.0x00
(la valeur numérique zéro) ou la chaîne0x00
(pour laquellelooks_like_number
est faux)? De toute façon, c'est déjà couvert.Perl n'a pas de type booléen natif, mais vous pouvez utiliser la comparaison d'entiers ou de chaînes afin d'obtenir le même comportement. L'exemple d'Alan est une belle façon de le faire en utilisant la comparaison d'entiers. Voici un exemple
Une chose que j'ai faite dans certains de mes programmes est d'ajouter le même comportement en utilisant une constante:
Les lignes marquées "use constant" définissent une constante nommée true qui évalue toujours à 1 et une constante nommée false qui évalue toujours par 0. En raison de la façon dont les constantes sont définies en Perl, les lignes de code suivantes échouent également:
Le message d'erreur doit dire quelque chose comme «Impossible de modifier la constante dans l'affectation scalaire».
Je l'ai vu dans l'un des commentaires que vous avez demandé sur la comparaison des chaînes. Vous devez savoir que parce que Perl combine des chaînes et des types numériques dans des variables scalaires, vous avez une syntaxe différente pour comparer les chaînes et les nombres:
La différence entre ces opérateurs est une source de confusion très courante en Perl.
la source
use warnings;
au lieu de#! perl -w
if ($exitstatus) { exit; }
vsif ($exitstatus == true) { exit; }
, qui pourrait ne pas être évident pour un observateur occasionnel. (Et oui, le dernier exemple est un mauvais style de programmation, mais c'est à côté du point).Je recommande
use boolean;
. Vous devez cependant installer le module booléen depuis cpan.la source
if ($my_true_value == true)
. Prétendre qu'il existe une seule vraie vérité est, selon mon expérience, un chemin vers la douleur et un code inefficace.Mes favoris ont toujours été
qui est complètement indépendant de la représentation interne.
la source
Je suis tombé sur un tutoriel qui a une bonne explication sur les valeurs vraies et fausses en Perl . Il déclare que:
Les valeurs scalaires suivantes sont considérées comme fausses:
undef
- la valeur indéfinie0
le nombre 0, même si vous l'écrivez en 000 ou 0,0''
la chaîne vide.'0'
la chaîne qui contient un seul chiffre 0.Toutes les autres valeurs scalaires, y compris les suivantes, sont vraies:
1
tout numéro différent de 0' '
la chaîne avec un espace'00'
deux ou plusieurs 0 caractères dans une chaîne"0\n"
un 0 suivi d'une nouvelle ligne'true'
'false'
oui, même la chaîne 'false' a la valeur true.Il existe un autre bon tutoriel qui explique le vrai et le faux de Perl .
la source
Belle explication donnée par bobf pour les valeurs booléennes: Vrai ou faux? Un guide de référence rapide
Tests de vérité pour différentes valeurs
la source
utilisez le préfixe de fichier suivant, cela ajoutera à votre script perl eTRUE et eFALSE, ce sera en fait REAL (!) vrai et faux (tout comme java)
Il y a, en fait, peu de raisons pour lesquelles vous devriez utiliser cela.
Ma raison est qu'en travaillant avec JSON, j'ai 0 et 1 comme valeurs pour les clés, mais ce hack s'assurera que les valeurs correctes sont conservées tout au long de votre script.
la source