Aller au contenu principal
Voir
Chapitre 2 / 16Les chaînes et les symboles
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 chaînes et les symboles

Ce guide approfondit les String et les Symbol introduits au chapitre 1. On découvre les outils que Ruby offre pour transformer, formater et comparer du texte.

Principe

On a vu qu'une String est du texte et qu'un Symbol est un identifiant. Dans ce chapitre, on va apprendre à manipuler les String : les modifier, les découper, les aligner. On verra aussi pourquoi les Symbol sont si importants et comment passer de l'un à l'autre.

Rappel : guillemets simples et doubles

Les guillemets simples créent un texte brut. Les guillemets doubles permettent l'interpolation (#{}) et les séquences d'échappement :

  • \n crée un retour à la ligne. \t crée une tabulation. Ces séquences ne fonctionnent qu'avec les guillemets doubles.
  • Règle simple : guillemets simples par défaut, guillemets doubles si on a besoin d'interpolation ou de \n.

Les textes multi-lignes (heredoc)

Pour écrire un texte sur plusieurs lignes sans enchaîner les \n, Ruby propose les heredoc :

description = <<~TEXT
Pikachu est un Pokémon de type Électrik.
Il évolue depuis Pichu par bonheur.
TEXT

puts description
  • <<~TEXT ouvre le heredoc. Le texte se termine quand Ruby rencontre TEXT seul sur une ligne.
  • Le ~ supprime l'indentation commune, ce qui permet d'indenter le texte dans le code sans que les espaces apparaissent à l'affichage.
  • Le mot TEXT est un choix arbitraire. On pourrait écrire <<~DESCRIPTION ou n'importe quel autre mot.

Interpolation vs concaténation

Il y a deux façons de combiner du texte et des variables. La première, l'interpolation, on la connaît déjà :

name = 'Dracaufeu'
level = 36

# Interpolation (à privilégier)
puts "#{name} est niveau #{level}"

# Concaténation (à éviter)
puts name + ' est niveau ' + level.to_s
  • L'interpolation convertit automatiquement les valeurs en texte. La concaténation exige un appel à .to_s sinon Ruby lève une erreur.
  • L'interpolation est plus lisible, plus courte, et plus performante. C'est toujours le bon choix.

Connaître la taille d'une String

puts 'Pikachu'.length # => 7
puts 'Pikachu'.size # => 7
puts ''.length # => 0
  • .length et .size font exactement la même chose. Utiliser l'un ou l'autre, c'est une question de préférence.

Changer la casse

Ruby offre plusieurs méthodes pour changer les majuscules et minuscules :

  • .upcase met tout en majuscules. .downcase met tout en minuscules.
  • .capitalize met la première lettre en majuscule et le reste en minuscules.
  • .swapcase inverse chaque lettre (majuscule devient minuscule et vice versa). C'est rarement utile, mais bon à connaître.

Supprimer les espaces

name = ' Pikachu '

puts name.strip # => "Pikachu" (supprime les espaces des deux côtés)
puts name.lstrip # => "Pikachu " (supprime à gauche seulement)
puts name.rstrip # => " Pikachu" (supprime à droite seulement)
  • .strip est très utile quand on récupère du texte saisi par un utilisateur, qui contient souvent des espaces en trop.

Chercher dans une String

puts 'Bulbizarre'.include?('zarre') # => true
puts 'Bulbizarre'.include?('Feu') # => false
puts 'Bulbizarre'.start_with?('Bulb') # => true
puts 'Bulbizarre'.end_with?('zarre') # => true
  • Ces méthodes retournent true ou false. Le ? à la fin est la convention Ruby pour les méthodes qui posent une question.
  • La recherche est sensible à la casse : 'Pikachu'.include?('pika') retourne false.

Remplacer du texte

phrase = 'Pikachu utilise Tonnerre. Pikachu gagne !'

# Remplacer la première occurrence
puts phrase.sub('Pikachu', 'Raichu')
# => Raichu utilise Tonnerre. Pikachu gagne !

# Remplacer toutes les occurrences
puts phrase.gsub('Pikachu', 'Raichu')
# => Raichu utilise Tonnerre. Raichu gagne !
  • .sub remplace uniquement la première occurrence. .gsub remplace toutes les occurrences (le g signifie "global").
  • Ces méthodes retournent une nouvelle String. L'originale n'est pas modifiée.

Répéter une String

L'opérateur * permet de répéter une String :

puts '=' * 30 # => ==============================
puts 'Pika' * 3 # => PikaPikaPika
  • C'est très pratique pour créer des lignes de séparation ou des barres visuelles.

Aligner du texte

Ruby permet d'aligner du texte dans un espace de largeur fixe :

puts 'Pikachu'.ljust(15) # => "Pikachu "
puts 'Pikachu'.rjust(15) # => " Pikachu"
puts 'Pikachu'.center(15) # => " Pikachu "
puts 'Pikachu'.center(15, '-') # => "----Pikachu----"
  • .ljust(n) aligne à gauche sur n caractères en remplissant avec des espaces à droite.
  • .rjust(n) aligne à droite. .center(n) centre le texte.
  • On peut remplacer l'espace par un autre caractère en le passant en second argument.

Formater des nombres dans du texte

Pour afficher un nombre avec un format précis (zéros en tête, décimales fixes), Ruby offre la méthode format :

pokedex_number = 6
health = 88.5

puts format('No.%03d', pokedex_number) # => No.006
puts format('PV: %.1f%%', health) # => PV: 88.5%
  • %03d signifie : un entier (d) sur au moins 3 caractères (3), complété par des zéros (0).
  • %.1f signifie : un nombre décimal (f) avec 1 chiffre après la virgule.
  • %% affiche un vrai % (sinon Ruby pense que c'est un format).

Les Symbol en profondeur

On a vu au chapitre 1 que les Symbol sont des identifiants. Voyons pourquoi ils sont différents des String :

# Deux Symbol identiques sont le même objet en mémoire
puts :fire.object_id # => toujours le même nombre
puts :fire.object_id # => exactement le même nombre

# Deux String identiques sont des objets différents
puts 'fire'.object_id # => un nombre
puts 'fire'.object_id # => un nombre différent !
  • Chaque fois qu'on écrit 'fire', Ruby crée un nouvel objet en mémoire. Chaque fois qu'on écrit :fire, Ruby réutilise le même objet.
  • C'est pour cela que la comparaison entre Symbol est instantanée : Ruby compare juste un numéro, pas chaque caractère un par un.

Convertir entre String et Symbol

type_symbol = :fire
type_string = type_symbol.to_s # => "fire"

type_string = 'water'
type_symbol = type_string.to_sym # => :water
  • .to_s convertit un Symbol en String. .to_sym convertit une String en Symbol.
  • On a parfois besoin de ces conversions pour afficher un Symbol (qui ne peut pas être interpolé tel quel sans .to_s, mais l'interpolation appelle .to_s automatiquement).

Quand utiliser String vs Symbol

  • Symbol : pour tout ce qui est un identifiant interne. Un type de Pokémon (:fire), un statut (:poisoned), une clé dans une structure de données.
  • String : pour tout ce qui est du texte affiché ou manipulé. Un nom de Pokémon ('Pikachu'), une description, un message.

En cas de doute : est-ce qu'on va afficher cette valeur à l'utilisateur ? Si oui, c'est une String. Est-ce qu'on va l'utiliser comme étiquette pour identifier quelque chose ? Si oui, c'est un Symbol.

Conclusion

  • Les guillemets simples créent un texte brut. Les guillemets doubles permettent l'interpolation et les séquences d'échappement (\n, \t).
  • Toujours préférer l'interpolation à la concaténation.
  • .upcase, .downcase, .capitalize changent la casse. .strip supprime les espaces.
  • .include?, .start_with?, .end_with? cherchent dans une String.
  • .sub remplace la première occurrence, .gsub toutes les occurrences.
  • * répète une String. .ljust, .rjust, .center alignent du texte.
  • format permet de formater des nombres avec des zéros en tête ou des décimales fixes.
  • Les Symbol sont immuables et uniques en mémoire. Utiliser .to_s et .to_sym pour convertir.