Ruby/Symboles
Il se peut que vous ayez besoin d'attribuer un objet unique à une variable. Dans certains cas, il est possible d’utiliser des chiffres, des booléens ou des chaînes de caractères, mais dans d'autres cas, il vous faudra utiliser des symboles.
Définition
[modifier | modifier le wikicode]Les symboles sont les objets les plus basiques en Ruby : un nom associé à un identifiant interne. À chaque fois que vous assignez le nom d'un symbole à un objet (une variable, par exemple), c’est toujours le même symbole qui est utilisé, donc par conséquent, le même objet tout au long du programme.
Concrètement, un symbole est un mot précédé de : (sans espace).
Ici, on a assigné la même valeur aux variables nom1
et nom2
, puis on a fait de même avec les variables nomA
et nomB
, à la différence qu'on leur a associé un symbole et non une chaîne de caractères.
Si on teste l'égalité de ces deux paires de variables, voici ce qu'on obtient :
if nom1 == nom2
puts "nom1 = nom2"
end
if nomA == nomB
puts "nomA = nomB"
end
# => nom1 = nom2
# => nomA = nomB
Les valeurs de ces objets sont identiques deux à deux. Mais lorsque l’on regarde les objets eux-mêmes :
if nom1.object_id == nom2.object_id
puts "nom1 = nom2"
end
if nomA.object_id == nomB.object_id
puts "nomA = nomB"
end
# => nomA = nomB
On peut donc en déduire que nom1
et nom2
possèdent la même information mais sont deux objets distincts, alors que nomA
et nomB
sont les mêmes objets (ils ont le même identifiant) : car ils sont associés à un seul et même objet de type Symbol
.
Lorsque l’on a déclaré nomA
et nomB
, un seul objet Symbol
a été créé, cela fait faire une économie au niveau de la mémoire et du temps d'exécution. Nous venons de voir que deux objets contenant la référence au même symbole sont identiques, alors que deux objets contenant simplement la même valeur sont différents. En effet :
puts :Karl.object_id # => 190778
puts nomA.object_id # => 190778
puts nomB.object_id # => 190778
puts nom1.object_id # => 21329010
puts nom2.object_id # => 21329000
Convertir chaînes et symboles
[modifier | modifier le wikicode]Pour transformer un symbole en chaîne de caractères, vous disposez des méthodes to_s
et id2name
(identiques) définies pour les objets Symbol
(Symbol#id2name
) :
Pour effectuer l'opération inverse, c'est-à-dire obtenir le symbole correspondant à une chaîne de caractères, nous utilisons la méthode intern
de la classe String
(String#intern
). Vous pouvez par exemple avoir l'identifiant interne du symbole associé à la chaîne de caractères :
Quand les utiliser ?
[modifier | modifier le wikicode]
Voici un programme d'exemple, pour les mettre en pratique.
class Ecolier
def initialize lang
@lang = lang
end
def lang
@lang.to_s
end
end
Jean = Ecolier.new :fr
Peter = Ecolier.new :en
Karl = Ecolier.new :en
puts Jean.lang, Peter.lang, Karl.lang
Nous avons une classe Ecolier
, la langue de l'écolier est stockée dans la variable @lang
. Vous avez sans doute remarqué que la langue de l'écolier (passée en paramètre lors de l'instanciation) est sous forme de symbole.
Prenons l'exemple de Jean
, sa langue est associée au symbole :fr
. Nous aurions aussi pu utiliser une chaîne de caractères pour représenter la langue, mais qu'aurions-nous mis ? "fr" ? "Fr" ? "français" ? "Français" ?
Dans ce cas, ce que contient la chaîne de caractères ne nous intéresse pas, seul le fait que Jean parle français est important. Nous choisissons donc un symbole. Il est de ce fait inutile de recréer une nouvelle chaîne de caractères pour chaque écolier parlant le Français, nous utiliserons l'unique symbole :fr
.
Le plus souvent, les symboles fournissent une alternative aux chaînes de caractères.