Les conditions
Ce chapitre présente les conditions, le mécanisme qui permet à un programme de prendre des décisions. Selon la situation, le code exécute une branche ou une autre.
Principe
Jusqu'ici, nos programmes s'exécutaient de haut en bas, ligne par ligne. Mais un programme utile doit pouvoir réagir : si le Pokémon est KO, afficher un message. Si l'attaque est super efficace, doubler les dégâts. C'est le rôle des conditions : tester une situation et agir en conséquence.
Vrai ou faux en Ruby (truthiness)
Avant de voir les conditions, il faut comprendre comment Ruby décide si quelque chose est "vrai" ou "faux".
La règle est très simple : seuls false et nil sont considérés comme faux. Tout le reste est vrai, même les valeurs qui semblent "vides" dans d'autres langages :
# Ces valeurs sont toutes considérées comme vraies
puts 'oui' if 0 # 0 est vrai !
puts 'oui' if '' # une String vide est vraie !
puts 'oui' if [] # un Array vide est vrai !
# Seuls false et nil sont faux
puts 'oui' if false # pas affiché
puts 'oui' if nil # pas affiché
- C'est une particularité de Ruby. Dans d'autres langages,
0ou""sont souvent faux. Pas en Ruby. - Pour tester si un nombre vaut zéro, on écrit
number == 0. Pour tester si une String est vide, on utilise.empty?.
if / elsif / else
La structure la plus courante pour exécuter du code selon une condition :
- Ruby évalue chaque condition de haut en bas et exécute la première qui est vraie.
elsif(paselseifnielse if) ajoute des conditions supplémentaires.elses'exécute quand aucune condition précédente n'est vraie. Il est optionnel.- Le bloc se termine par
end.
Un if simple sans elsif ni else :
health_points = 0
if health_points <= 0
puts 'Le Pokémon est KO !'
end
unless
unless est l'inverse de if. Il exécute le code quand la condition est fausse :
held_item = nil
unless held_item
puts 'Le Pokémon ne tient aucun objet.'
end
unless held_itemveut dire "siheld_itemest faux (c'est-à-direniloufalse)".unlessrend le code plus lisible quand on teste une négation simple. La règle d'or est d'éviter les doubles négations :unless !conditionest déroutant, un simpleif conditionest bien plus clair.unlessavec&&est acceptable tant que la phrase reste facile à comprendre. En revanche, éviterunlessavecelse: si on a besoin d'unelse, c'est qu'unifserait plus lisible.
Forme postfixe (sur une ligne)
Quand le code à exécuter tient sur une seule ligne, on peut mettre la condition à la fin :
level = 100
health_points = 0
puts 'Niveau maximum !' if level >= 100
puts 'Le Pokémon est KO !' if health_points <= 0
puts 'Le Pokémon est en forme.' unless health_points <= 0
- C'est exactement la même chose qu'un
if ... end, mais plus compact. - On lit naturellement : "affiche ce message si le niveau est supérieur ou égal à 100".
- À utiliser uniquement quand le code tient sur une ligne. Pour les blocs plus longs, garder la forme classique.
case / when
Quand on compare une même valeur à plusieurs possibilités, case/when est plus lisible qu'une série de if/elsif :
caseprend la valeur à comparer. Chaquewhenteste une possibilité.- Un seul
whens'exécute (pas de "fall-through" comme en C ou JavaScript). elseest optionnel, il couvre tous les cas non listés.
case/when fonctionne aussi avec des ranges (intervalles) :
level = 45
case level
when 1..30
puts 'Bas niveau'
when 31..60
puts 'Niveau moyen'
when 61..100
puts 'Haut niveau'
end
1..30est un Range (intervalle) qui inclut 1 et 30. Ruby vérifie silevelest dans cet intervalle.
Et avec des classes (types) :
value = 42
case value
when Integer
puts 'Un nombre entier'
when String
puts 'Du texte'
when Symbol
puts 'Un symbole'
end
Les opérateurs de comparaison
puts 50 == 50 # => true (égal)
puts 50 != 75 # => true (différent)
puts 50 < 75 # => true (inférieur)
puts 50 > 75 # => false (supérieur)
puts 50 <= 50 # => true (inférieur ou égal)
puts 50 >= 75 # => false (supérieur ou égal)
==compare les valeurs. Attention à ne pas confondre avec=qui est l'affectation.
Il existe aussi l'opérateur "vaisseau spatial" <=> qui retourne -1, 0 ou 1 :
puts 10 <=> 20 # => -1 (10 est plus petit)
puts 20 <=> 20 # => 0 (égaux)
puts 30 <=> 20 # => 1 (30 est plus grand)
<=>est utilisé par.sortpour comparer les éléments entre eux. On le reverra dans les chapitres suivants.
Les opérateurs logiques
Pour combiner plusieurs conditions, on utilise && (et), || (ou) et ! (non) :
level = 80
is_legendary = false
# && : les DEUX conditions doivent être vraies
if level >= 50 && !is_legendary
puts 'Pokémon puissant et non légendaire'
end
# || : au moins UNE condition doit être vraie
if is_legendary || level >= 80
puts 'Pokémon rare !'
end
# ! : inverse la valeur
if !is_legendary
puts 'Pokémon non légendaire'
end
&&retournetruesi les deux côtés sont vrais.||retournetruesi au moins un côté est vrai.!inverse :!truedonnefalse,!falsedonnetrue,!nildonnetrue.
Ruby propose aussi and, or et not qui font la même chose mais avec une priorité plus basse. En pratique, toujours utiliser &&, || et ! pour éviter les surprises.
L'opérateur ||= (ou-égal)
||= est un raccourci très courant. Il assigne une valeur uniquement si la variable est nil ou false :
ability = nil
ability ||= :static
puts ability # => static (ability était nil, donc :static a été assigné)
ability ||= :lightning_rod
puts ability # => static (ability avait déjà une valeur, rien ne change)
ability ||= :staticest équivalent àability = ability || :static.- Si
abilityestnil,||prend la valeur de droite (:static). Siabilitya déjà une valeur,||garde celle de gauche. - C'est très pratique pour définir des valeurs par défaut.
L'opérateur ternaire
Pour choisir entre deux valeurs en une seule ligne :
level = 50
category = level >= 50 ? 'fort' : 'faible'
puts category # => fort
condition ? valeur_si_vrai : valeur_si_fauxest un raccourci pour unif/elsequi retourne une valeur.- À utiliser quand le choix est simple et tient sur une ligne. Pour les cas plus complexes, préférer
if/else.
Conclusion
- En Ruby, seuls
falseetnilsont faux. Tout le reste (0,"",[]) est vrai. if/elsif/else/endpour les conditions. Le mot-clé estelsif(paselseif).unlesspour les négations simples. Ne pas l'utiliser avecelseou des conditions composées.- La forme postfixe (
puts 'message' if condition) est idéale pour les lignes simples. case/whencompare une valeur à plusieurs possibilités (valeurs, ranges, classes).==compare les valeurs.&&(et),||(ou),!(non) combinent les conditions.||=assigne une valeur uniquement si la variable estniloufalse.- L'opérateur ternaire
condition ? vrai : fauxchoisit entre deux valeurs en une ligne.