Aller au contenu principal
Voir
Chapitre 5 / 16Les conditions
1. Les variables et les types de données
2. Les chaînes et les symboles
3. Les tableaux
4. Les tables associatives
5. Les conditions
6. Les boucles et les itérateurs
7. Les méthodes et les blocs
8. Les classes et les objets
9. L'héritage
10. Les modules
11. Étendre du code avec prepend
12. Enumerable
13. Pour aller plus loin
14. La gestion des erreurs
15. Lire et écrire des fichiers
16. Les fonctionnalités avancées des classes

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, 0 ou "" 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 (pas elseif ni else if) ajoute des conditions supplémentaires.
  • else s'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_item veut dire "si held_item est faux (c'est-à-dire nil ou false)".
  • unless rend le code plus lisible quand on teste une négation simple. La règle d'or est d'éviter les doubles négations : unless !condition est déroutant, un simple if condition est bien plus clair. unless avec && est acceptable tant que la phrase reste facile à comprendre. En revanche, éviter unless avec else : si on a besoin d'un else, c'est qu'un if serait 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 :

  • case prend la valeur à comparer. Chaque when teste une possibilité.
  • Un seul when s'exécute (pas de "fall-through" comme en C ou JavaScript).
  • else est 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..30 est un Range (intervalle) qui inclut 1 et 30. Ruby vérifie si level est 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 .sort pour 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
  • && retourne true si les deux côtés sont vrais.
  • || retourne true si au moins un côté est vrai.
  • ! inverse : !true donne false, !false donne true, !nil donne true.

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 ||= :static est équivalent à ability = ability || :static.
  • Si ability est nil, || prend la valeur de droite (:static). Si ability a 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_faux est un raccourci pour un if/else qui 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 false et nil sont faux. Tout le reste (0, "", []) est vrai.
  • if/elsif/else/end pour les conditions. Le mot-clé est elsif (pas elseif).
  • unless pour les négations simples. Ne pas l'utiliser avec else ou des conditions composées.
  • La forme postfixe (puts 'message' if condition) est idéale pour les lignes simples.
  • case/when compare une valeur à plusieurs possibilités (valeurs, ranges, classes).
  • == compare les valeurs. && (et), || (ou), ! (non) combinent les conditions.
  • ||= assigne une valeur uniquement si la variable est nil ou false.
  • L'opérateur ternaire condition ? vrai : faux choisit entre deux valeurs en une ligne.