Retour au cours

symboles vs. chaînes de caractères

Objectifs

  • Définir ce qu’est un Symbol en Ruby.
  • Comprendre la différence fondamentale en termes de performance et d’utilisation mémoire.
  • Savoir pourquoi les symboles sont le choix par défaut pour les clés de Hash.

À première vue, un symbole comme :nom et une chaîne "nom" peuvent sembler similaires, mais ils sont conceptuellement et techniquement très différents.

Les Chaînes de caractères (String)

  • Rôle : Représentent des données textuelles. Le contenu est important et est destiné à être lu, affiché ou manipulé.
  • Mutabilité : Les chaînes sont mutables. On peut modifier leur contenu.
  • Identité : Chaque fois que vous créez une chaîne, Ruby alloue un nouvel objet en mémoire, même si le contenu est identique.
# Ces deux chaînes ont le même contenu, mais sont deux objets différents
"hello".object_id  # => 70146014490760
"hello".object_id  # => 70146014483720 (un ID différent)

Les Symboles (Symbol)

  • Rôle : Représentent des identifiants, des noms, des étiquettes. Leur contenu n’est pas fait pour être manipulé, il sert juste de nom constant.
  • Immutabilité : Les symboles sont immuables. Une fois créés, ils ne peuvent pas être modifiés.
  • Identité : Un symbole est unique et garanti d’être unique pour toute la durée d’exécution du programme. Toutes les occurrences du même symbole (ex: :nom) pointent vers le même et unique objet en mémoire.
# Ces deux symboles sont en réalité le même et unique objet
:hello.object_id   # => 1089068
:hello.object_id   # => 1089068 (le MÊME ID)

Pourquoi utiliser des Symboles comme clés de Hash ?

C’est le cas d’usage le plus courant, et la raison de la syntaxe moderne des hashes ({ nom: "Alice" }).

  1. Performance : Lorsque vous cherchez une clé dans un hash (mon_hash[:nom]), si la clé est un symbole, Ruby peut comparer les object_id directement. C’est une opération extrêmement rapide. Si la clé était une chaîne, Ruby devrait comparer le contenu des deux chaînes, caractère par caractère, ce qui est beaucoup plus lent, surtout pour de gros hashes.

  2. Efficacité mémoire : Si vous utilisez la chaîne "nom" comme clé dans 1000 hashes différents, vous créez 1000 objets "nom" en mémoire. Si vous utilisez le symbole :nom, vous n’avez qu’un seul objet :nom partagé par tous, ce qui économise de la mémoire.

Résumé : Quand utiliser quoi ?

  • Utilisez une String si la valeur textuelle est une donnée qui a de l’importance et que vous pourriez avoir besoin de manipuler. (Ex: un nom d’utilisateur, un article de blog, une adresse email).

  • Utilisez un Symbol si vous avez besoin d’un identifiant simple, rapide et constant. (Ex: les clés d’un hash, le nom d’une méthode, un statut comme :en_cours ou :termine).

Bonnes pratiques

  • La convention est claire : Toujours utiliser des symboles pour les clés de vos hashes.
  • Pensez aux symboles comme des “étiquettes” et aux chaînes comme des “données textuelles”.

Exercices

  1. Vérification dans irb :

    • Lancez irb.
    • Vérifiez par vous-même la différence d’object_id en exécutant :
      "ma_chaine".object_id
      "ma_chaine".object_id
      :mon_symbole.object_id
      :mon_symbole.object_id
  2. Conversion :

    • On peut facilement passer de l’un à l’autre.
    • Dans irb, essayez "ma_chaine".to_sym. Quel est le résultat ?
    • Essayez :mon_symbole.to_s. Quel est le résultat ?
  3. Le mauvais Hash :

    • Créez un hash en utilisant la syntaxe “hash rocket” et des chaînes de caractères comme clés. personne = { "nom" => "Alice", "age" => 30 }
    • Comment accédez-vous à l’âge de la personne ? Est-ce personne[:age] ou personne["age"] ? Testez et comprenez la différence.