Comment comprendre les symboles en Ruby
Malgré la lecture de "La Compréhension De Ruby Symboles", je suis toujours confus par la représentation des données dans la mémoire quand il s'agit de l'utilisation de symboles. Si un symbole, deux d'entre eux contenues dans des objets différents, existent dans le même emplacement de mémoire, alors comment est-il qu'ils contiennent différents valeurs? J'aurais attendu le même emplacement de mémoire pour contenir la même valeur.
Ce un devis à partir du lien:
À la différence des chaînes de caractères, symboles du même nom sont initialisés et d'exister dans la mémoire qu'une seule fois au cours d'une session de ruby
Je ne comprends pas comment il parvient à différencier les valeurs contenues dans le même emplacement de mémoire.
Considérons cet exemple:
patient1 = { :ruby => "red" }
patient2 = { :ruby => "programming" }
patient1.each_key {|key| puts key.object_id.to_s}
3918094
patient2.each_key {|key| puts key.object_id.to_s}
3918094
patient1
et patient2
sont à la fois des tables de hachage, c'est bien. :ruby
, cependant, est un symbole. Si nous étions de sortie suivants:
patient1.each_key {|key| puts key.to_s}
Puis ce sera sortie? "red"
, ou "programming"
?
Oublier hachages pour une seconde, je pense à un symbole est un pointeur à une valeur. Les questions que j'ai sont:
- Puis-je assigner une valeur à un symbole?
- Est un symbole juste un pointeur vers une variable avec une valeur en elle?
- Si les symboles sont mondiaux, cela signifie un symbole renvoie toujours à une chose?
- Il sera sortie ":ruby", parce que vous êtes l'impression d'un Symbole. Si vous dites
puts patient1[:ruby]
, il affichera "rouge", si vous ditesputs patient2[:ruby]
, il aura l'impression de "programmation". - Un symbole n'est PAS un pointeur vers une valeur. En interne, un symbole est juste un entier.
Vous devez vous connecter pour publier un commentaire.
Considérez ceci:
Si, toutefois, vous créez un objet symbole, tant que son contenu sont les mêmes, il va se référer au même objet en mémoire. Ce n'est pas un problème, car un symbole est un immuable objet. Les chaînes sont mutables.
(En réponse à la remarque ci-dessous)
Dans l'article original, la valeur n'est pas stockée dans un symbole, elle est stockée dans une table de hachage. Considérez ceci:
Cela crée six objets dans la mémoire -- quatre objets string et deux de hachage objets.
Cela ne crée de cinq objets en mémoire -- un symbole, deux chaînes et deux de hachage objets.
Hash
(créé par {... => ...} dans le code) qui stocke des paires clé/valeur, pas laSymbol
s eux-mêmes. LeSymbol
s (par exemple:symbol
ou:sym
ou:ruby
) sont les clés de paires. Uniquement dans le cadre d'unHash
- ils "point" de quoi que ce soit.J'ai été en mesure de grock symboles quand je pensais à elle comme ça. Un Rubis chaîne de caractères est un objet qui a un tas de méthodes et de propriétés. Les gens aiment utiliser les cordes pour les clés, et lorsque la chaîne est utilisé pour une clé, puis toutes les méthodes ne sont pas utilisées. Donc, ils ont fait des symboles, qui sont des objets de chaîne avec toutes les fonctionnalités supprimées, à l'exception de ce qui est nécessaire pour une bonne clé.
Il suffit de penser de symboles comme les chaines.
Le symbole
:ruby
ne contient pas de"red"
ou"programming"
. Le symbole:ruby
est juste le symbole:ruby
. Il est de votre hache,patient1
etpatient2
qui contiennent chacune de ces valeurs, dans chaque cas signalé par la même clé.Pensez-y de cette façon: Si vous allez dans le salon le matin de noël, et de voir deux boîtes avec une étiquette sur eux que de dire "Kezzer" sur eux. Sur a des chaussettes en elle, et l'autre a charbon. Vous n'allez pas à se confondre et se demander comment "Kezzer" peut contenir à la fois des chaussettes et du charbon, même si c'est le même nom. Parce que le nom n'est pas contenant le (de merde) présente. C'est juste pointant sur eux. De même,
:ruby
ne contient pas de valeurs de hachage, c'est juste des points à eux.mystring = :steveT
le symbole n'est pas pour rien. Une Clé dans une table de hachage a une valeur associée, et la clé pourrait être un symbole. Mais un symbole n'a pas besoin d'être dans une table de hachage.Vous pourriez être en supposant que la déclaration que vous avez faite définit la valeur d'un Symbole à être autre chose que ce qu'il est. En fait, un Symbole est juste un "internalisés" Chaîne de valeur reste constante. C'est parce qu'ils sont stockés à l'aide d'un simple identifiant entier qu'ils sont fréquemment utilisés comme qui est plus efficace que la gestion d'un grand nombre de chaînes de longueur variable.
Prenons le cas de votre exemple:
Ce doit être lu comme suit: "déclarer une variable patient1 et de définir une table de Hachage, et dans ce magasin, la valeur "rouge" sous la clé (symbole 'ruby')"
Une autre façon d'écrire c'est:
Que vous êtes une assignation, il n'est guère surprenant que le résultat que vous obtenez en retour est identique à ce que vous avez attribué à en premier lieu.
Le Symbole concept peut être un peu déroutant, car il n'est pas une caractéristique de la plupart des autres langues.
Chaque Chaîne de l'objet est visible, même si les valeurs sont identiques:
Chaque Symbole avec la même valeur se réfère au même objet:
Conversion de chaînes de symboles de cartes de valeurs identiques pour le même Symbole unique:
De même, la conversion du Symbole à la Chaîne crée un distinctes de chaîne à chaque fois:
Vous pouvez penser à des valeurs de Symbole comme étant prélevé à partir d'une table de Hachage interne et vous pouvez voir toutes les valeurs qui ont été codées à l'aide de Symboles à l'aide d'un simple appel de méthode:
Que vous définissez de nouveaux symboles, soit par le colon-notation ou par l'aide .to_sym ce tableau va croître.
Symboles ne sont pas des pointeurs. Ils ne contiennent pas de valeurs. Symboles simplement sont.
:ruby
est le symbole:ruby
et c'est tout là est à lui. Il ne contient pas une valeur, il n'a pas ne, ça c'est juste existe en tant que symbole:ruby
. Le symbole:ruby
est une valeur tout comme le nombre 1 est. Il n'a pas de point à l'autre de la valeur, pas plus que le nombre 1 n'.Ni, il sera sortie "ruby".
Vous êtes à la confusion des symboles et des valeurs de hachage. Ils ne sont pas liés, mais ils sont utiles ensemble. Le symbole en question est
:ruby
; il n'a rien à voir avec les valeurs dans la table de hachage, et c'interne de représentation entière sera toujours le même, et c'est la "valeur" (lors de la conversion d'une chaîne de caractères) sera toujours "ruby".En bref
Symboles de résoudre le problème de la création de l'homme lisible, immuable représentations qui ont également l'avantage d'être plus simple pour le moteur d'exécution pour la recherche de chaînes. Pensez-y comme un nom ou une étiquette qui peut être réutilisé.
Pourquoi :le rouge est mieux que "rouge"
Dans la dynamique des langages orientés objets que vous créez complexes, imbriquées structures de données lisibles par des références. La de hachage est une commune de cas d'utilisation vous permet de mapper des valeurs de clés uniques — unique, au moins, pour chaque instance. Vous ne pouvez pas avoir plus d'un "rouge" clé par hachage.
Cependant, il serait processeur plus efficace d'utiliser un index numérique à la place des clés de chaîne. Si les symboles ont été présenté comme un compromis entre la vitesse et la lisibilité. Les symboles de résoudre beaucoup plus facile que la chaîne équivalente. En étant lisible et facile pour le moteur d'exécution pour résoudre les symboles sont un complément idéal à un langage dynamique.
Avantages
Puisque les symboles sont immuables, ils peuvent être partagés entre le moment de l'exécution. Si deux instances de hachage ont un point en commun lexicographique ou sémantique besoin d'un objet rouge le symbole :rouge serait d'utiliser à peu près la moitié de la mémoire que la chaîne "rouge" aurait requis pour les deux hachages.
Depuis :rouge résout toujours vers le même emplacement en mémoire, il peut être réutilisé dans une centaine de hachage cas, avec presque pas d'augmentation de la mémoire, tandis que l'utilisation de "rouge" va ajouter une mémoire coûts, car chaque hachage instance aurait besoin de stocker les mutable chaîne lors de la création.
Pas sûr de savoir comment Ruby en fait met en œuvre les symboles/string mais clairement un symbole offre moins de mise en œuvre de surcharge lors de l'exécution puisque c'est un fixe de la représentation. En Plus des symboles prend un moins de caractères à taper qu'une chaîne de caractères entre guillemets et moins de frappe est l'éternelle quête du vrai Rubyists.
Résumé
Avec un symbole comme :rouge, vous obtenez la lisibilité de la représentation de chaîne avec moins de frais généraux en raison du coût de la chaîne d'opérations de comparaison et de la nécessité de stocker chaque instance de chaîne dans la mémoire.
Ni, bien sûr. La sortie sera
ruby
. Qui, d'ailleurs, vous auriez pu apprendre en moins de temps qu'il vous a fallu pour le type de la question, simplement en tapant dans la CISR à la place.Pourquoi serait il
red
ouprogramming
? Symboles toujours évaluer à eux-mêmes. La valeur du symbole:ruby
est le symbole:ruby
lui-même et la représentation de chaîne du symbole:ruby
est la valeur de la chaîne"ruby"
.[BTW:
puts
convertit toujours ses arguments à cordes, de toute façon. Il n'y a pas besoin d'appelerto_s
sur elle.]Je vous recommande de lire les Article de wikipédia sur les tables de hachage - je pense que ce sera vous aider à obtenir une idée de ce que
{:ruby => "red"}
signifie vraiment.Un autre exercice qui pourrait aider votre compréhension de la situation: considérer
{1 => "red"}
. Du point de vue sémantique, cela ne veut pas dire "définir la valeur de1
à"red"
", ce qui est impossible en Ruby. Plutôt, cela signifie "créer un De hachage objet, et de stocker la valeur"red"
pour la clé1
.Je suis nouveau à Ruby, mais je pense (espère?) c'est une manière simple de le regarder...
Un symbole n'est pas une variable ou une constante. Il ne se place pas dans, ou point de, une valeur. Un symbole EST une valeur.
Tous, c'est une chaîne sans que l'objet de frais généraux. Le texte et que le texte.
Donc, c':
Est le même que celui de:
Sauf que vous ne pouvez pas le faire, par exemple, :hellobuddy.upcase. C'est la chaîne de valeur et SEULE la chaîne de valeur.
Même, c':
Est le même que celui de:
Mais, encore une fois, sans la chaîne de l'objet de frais généraux.
Un moyen facile pour envelopper votre tête autour de ce qui est à penser, "si je à l'aide d'une chaîne plutôt qu'un symbole?
Il n'est pas confus du tout, pas vrai?
Vous êtes à l'aide de "ruby" comme l'un des principaux dans une table de hachage.
"ruby"
est un littéral de chaîne, de sorte que c'est la valeur. L'adresse de la mémoire, ou un pointeur, n'est pas disponible pour vous.Chaque fois que vous appelez
"ruby"
, vous créez une nouvelle instance de ce qui est, la création d'une nouvelle cellule de mémoire contenant la même valeur"ruby"
.Le hachage va alors "quelle est ma valeur de clé? Oh c'est
"ruby"
. Ensuite, des cartes de valeur "rouge" ou "programmation".En d'autres termes,
:ruby
n'a pas de déréférencement à"red"
ou"programming"
.Le hachage cartes
:ruby
à"red"
ou"programming"
.Comparer que si nous utilisons les symboles
La valeur de
:ruby
est également"ruby"
, effectivement.Pourquoi? Parce que les symboles sont essentiellement constantes de chaîne.
Les constantes de ne pas avoir plusieurs instances. C'est la même adresse mémoire. Et une adresse de mémoire a une certaine valeur, une fois déréférencé. Pour les symboles, le pointeur de nom est le symbole, et la déréférencé valeur est une chaîne, qui correspond au nom de symbole, dans ce cas,
"ruby"
.Lorsque dans une table de hachage, vous n'êtes pas en utilisant le symbole, le pointeur, mais le deferenced valeur. Vous n'êtes pas à l'aide de
:ruby
, mais"ruby"
.Le hachage recherche ensuite la clé
"ruby"
, la valeur est"red"
ou"programming"
, selon la façon dont vous avez défini le hachage.Le changement de paradigme et take-home concept est qu'un symbole de valeur est un tout autre concept à partir d'une valeur mappée par une table de hachage, de donner une clé de hachage.