Comment l'opérateur conditionnel ( ? :
) est-il utilisé dans Ruby?
Par exemple, est-ce correct?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Comment l'opérateur conditionnel ( ? :
) est-il utilisé dans Ruby?
Par exemple, est-ce correct?
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Réponses:
Il s'agit de l' opérateur ternaire , et il fonctionne comme en C (les parenthèses ne sont pas obligatoires). C'est une expression qui fonctionne comme:
if_this_is_a_true_value ? then_the_result_is_this : else_it_is_this
Cependant, en Ruby, if
c'est aussi une expression donc:if a then b else c end
=== a ? b : c
, sauf pour les problèmes de priorité. Les deux sont des expressions.
Exemples:
puts (if 1 then 2 else 3 end) # => 2
puts 1 ? 2 : 3 # => 2
x = if 1 then 2 else 3 end
puts x # => 2
Notez que dans le premier cas, des parenthèses sont requises (sinon Ruby est confus car il pense qu'il est puts if 1
avec des ordures supplémentaires après), mais elles ne sont pas requises dans le dernier cas car ledit problème ne se pose pas.
Vous pouvez utiliser le formulaire "long-if" pour la lisibilité sur plusieurs lignes:
question = if question.size > 20 then
question.slice(0, 20) + "..."
else
question
end
nil
et false
. Pas très habituel, en effet.
puts true ? "true" : "false"
=> "true"
puts false ? "true" : "false"
=> "false"
puts (true ? "true" : "false")
avec parenthèses. Sinon, l'ordre des opérations n'est pas clair. Lorsque j'ai lu ceci pour la première fois, j'étais confus car je l'ai lu car je (puts true) ? "true" : "false"
m'attendais puts
à retourner le booléen qui est ensuite devenu la valeur de chaîne.
Votre utilisation d'ERB suggère que vous êtes dans Rails. Si tel est le cas, envisagez truncate
un assistant intégré qui fera le travail pour vous:
<% question = truncate(question, :length=>30) %>
@pst a donné une excellente réponse, mais je voudrais mentionner que dans Ruby, l'opérateur ternaire est écrit sur une ligne pour être syntaxiquement correct, contrairement à Perl et C où nous pouvons l'écrire sur plusieurs lignes:
(true) ? 1 : 0
Normalement, Ruby génère une erreur si vous essayez de la diviser sur plusieurs lignes, mais vous pouvez utiliser le \
symbole de continuation de ligne à la fin d'une ligne et Ruby sera satisfait:
(true) \
? 1 \
: 0
C'est un exemple simple, mais il peut être très utile lorsqu'il s'agit de lignes plus longues car il garde le code bien présenté.
Il est également possible d'utiliser le ternaire sans les caractères de continuation de ligne en plaçant les opérateurs en dernier sur la ligne, mais je ne l'aime pas ou ne le recommande pas:
(true) ?
1 :
0
Je pense que cela conduit à un code très difficile à lire car le test conditionnel et / ou les résultats s'allongent.
J'ai lu des commentaires disant de ne pas utiliser l'opérateur ternaire parce que c'est déroutant, mais c'est une mauvaise raison de ne pas utiliser quelque chose. Par la même logique, nous ne devrions pas utiliser d'expressions régulières, d'opérateurs de plage (' ..
' et la variation "flip-flop" apparemment inconnue). Ils sont puissants lorsqu'ils sont utilisés correctement, nous devons donc apprendre à les utiliser correctement.
Pourquoi avez-vous mis des crochets autour
true
?
Prenons l'exemple du PO:
<% question = question.size > 20 ? question.question.slice(0, 20)+"..." : question.question %>
Envelopper le test conditionnel permet de le rendre plus lisible car il sépare visuellement le test:
<% question = (question.size > 20) ? question.question.slice(0, 20)+"..." : question.question %>
Bien sûr, l'exemple entier pourrait être rendu beaucoup plus lisible en utilisant quelques ajouts judicieux d'espaces. Ceci n'est pas testé mais vous aurez l'idée:
<% question = (question.size > 20) ? question.question.slice(0, 20) + "..." \
: question.question
%>
Ou, plus écrit de façon plus idiomatique:
<% question = if (question.size > 20)
question.question.slice(0, 20) + "..."
else
question.question
end
%>
Il serait facile d'argumenter que la lisibilité en souffre question.question
également.
true
?
true
c'est vraiment une expression qui évalue à true
ou false
. Il est préférable de les délimiter visuellement, car les déclarations ternaires peuvent rapidement se transformer en bruit visuel, ce qui réduit la lisibilité, ce qui affecte la maintenabilité.
Un exemple simple où l'opérateur vérifie si l'identifiant du joueur est 1 et définit l'identifiant ennemi en fonction du résultat
player_id=1
....
player_id==1? enemy_id=2 : enemy_id=1
# => enemy=2
Et j'ai trouvé un article sur le sujet qui semble assez utile.
enemy_id = player_id == 1 ? 2 : 1
?
Le code condition ? statement_A : statement_B
est équivalent à
if condition == true
statement_A
else
statement_B
end
Manière la plus simple:
param_a = 1
param_b = 2
result = param_a === param_b ? 'Same!' : 'Not same!'
puisque param_a
n'est pas égal à param_b
alors la result
valeur de seraNot same!
question=question[0,20]
s'il était inférieur à 20, cela ne changera rien.