Attribution de l'aide opérateur ternaire?
Je suis sur Perl 5.8 et je suis besoin d'assigner une valeur par défaut. J'ai fini par faire ceci:
if ($model->test) {
$review = "1"
} else {
$review = ''
}
La valeur de $model->test
va être "1"
ou non. Si il y a quelque chose dans $model->test
, ensemble $review
à "1"
contraire égal à ''
.
Car il n'est pas Perl 5.10, je ne peux pas utiliser le nouveau chic défini-ou de l'exploitant. Ma première réaction a été d'utiliser l'opérateur ternaire comme ça...
defined($model->test) ? $review = "1" : $review = '';
mais cela ne fonctionne pas non plus.
Quelqu'un a une idée comment faire pour affecter plus efficacement?
Janie
- Vous devriez vraiment mis à
!1
de ne pas''
. Ils ont tous deux la même représentation de chaîne (''
). La seule différence est que''
avertira si vous essayez de l'utiliser comme un certain nombre, où que!1
d'habitude. ( En supposant que vous avez toujoursuse warnings;
en haut de chaque morceau de code Perl comme vous le devriez. )
Vous devez vous connecter pour publier un commentaire.
J'avais l'habitude d'écrire ce que:
où les parenthèses sont pour plus de clarté pour les autres, la lecture du code.
defined
dans cette réponse. Plus il pourrait provoquer l'interruption du code de l'avenir, si la méthode commence par le retour''
ou0
au lieu deundef
.1
etundef
. Je suis d'accord qu'il est possible ici de supprimer l'ambiguïté autour de défini-mais-invalide en retour des valeurs telles que la0
; cependant, je suis en désaccord que cette ambiguïté doit être retiré par un simple booléen-tester la valeur de retour. Ceci est particulièrement pertinent en vertu de l'use warnings
, où la variante que vous impliquent de manière fiable provoquer un avertissement à chaque fois queundef
est retourné.my $review = !! $model->test;
qui est aussi court que vous pourriez peut-être obtenir, et montrent encore que l'intention de la valeur de retour est True/False. Aussi ce que vous avez ici doit être réduite à$review = defined $mode->test
.Vous avez un problème de priorité. Ce que vous avez est la même que
Vous pourriez le faire fonctionner avec des parens.
Mais c'est beaucoup plus propre à déplacer la cession de sortir.
Bien sûr, vous pouvez simplement utiliser
Mais pourquoi changer le fnud à une chaîne vide?
Alors il suffit d'utiliser cette:
En plus de l'opérateur conditionnel, j'ai souvent envie de l'utiliser
do
, qui retourne la valeur de la dernière expression évaluée:Tout d'abord, "Qui ne fonctionne pas non plus" n'est pas le plus utile que vous pourriez nous dire. Il est important de savoir exactement comment il ne fonctionne pas: ce ne il ne, à quoi vous attendiez-vous, et comment ils diffèrent?
Mais le problème avec
est la priorité de l'opérateur. L'opérateur conditionnel
? :
se lie plus étroitement que l'opérateur d'affectation=
, de sorte que le ci-dessus est équivalente à:Donc si
$model->test
est défini, il ne l'équivalent deVous pouvez résoudre ce problème avec des parenthèses:
Mais vraiment, pourquoi voudriez-vous? Le conditionnel (ternaire) opérateur est utile lorsque vous souhaitez utiliser le résultat. Si le résultat va être mis au rebut, comme il est ici, c'est plus clair (et, comme vous l'avez vu, moins d'erreurs) pour utiliser un if/else:
ou, si vous insistez sur l'écrire sur une seule ligne:
Si vous voulez vraiment utiliser une expression conditionnelle, vous pouvez le faire:
qui est probablement une façon raisonnable de le faire.
MAIS :
La
defined
opérateur se donne soit"1"
(true) ou""
(false). si le tout peut être réduit à:undef
est juste une fausse valeur, et la méthode est ré-écrit pour revenir''
ou0
comme une valeur fausse?defined
à elle. Vous aurez évidemment besoin de savoir ce que le retour de la méthode pour être en mesure de l'utiliser.Je suppose que
$model->test
est censé renvoyer une valeur true ou false.Sauf s'il est expressément précisé que la valeur false est
undef
, la méthode pourrait être réécrit pour commencer à retourner quelques autres valeur false à la place.Qui casserait tout ce qui vérifie uniquement si la valeur est définie.
( Je pense que c'est un bug que la méthode renvoie
undef
au lieu de l'canonique valeur false. )De sorte que la meilleure façon de mettre en
$review
est de tester la véracité de la valeur retournée; elle est definedness.Je tiens à souligner que cela a encore un bug.
Si vous voulez être en mesure d'utiliser la valeur comme un nombre, il émet des avertissements si elle était fausse.
Pour corriger cela, il faut retourner
!1
(canonique valeur false), qui renvoie une valeur qui est la chaîne de''
, mais aussi a la valeur numérique de 0.Avis qu'il pourrait être simplifié pour seulement:
Si vous voulez seulement changer la valeur uniquement lorsque c'est faux, vous pouvez utiliser l'opérateur ou
||
.Si vraiment vous voulez savoir si elle est définie, ou pas, pourquoi ne pas simplement utiliser
défini
.Si vous souhaitez modifier la valeur seulement quand il n'est pas défini, et vous avez Perl 5.10 ou plus récent, vous pouvez utiliser les définis-ou de l'exploitant (
//
).Sur un vieux Perl, qui exigerait plus d'un déclaration.
$result
à peu près la même valeur que juste$result = defined $model->test;
. La principale différence étant que vous avertira si utilisé comme un nombre.