Pourquoi l'absence de l'opérateur d'affectation me permet de modifier une constante Ruby sans avertissement du compilateur?

StackOverflow https://stackoverflow.com/questions/670094

Question

Dans les deux exemples suivants, je fais la même chose, ce qui crée une chaîne constante et en utilisant la méthode concat pour le modifier. Parce que c'est une constante, j'attends un avertissement du compilateur, mais seulement recevoir un dans le second exemple lorsque j'utilise l'opérateur d'affectation. Pourquoi est-ce?

X = "hello"
X.concat(" world")
puts X # no warning

X = "hello"
X = X.concat(" world")
puts X # warning: already initialized

Puisque la méthode concat modifie la chaîne en place, qui est normalement ce que je ferais, car il n'y a pas besoin d'utiliser un opérateur de assigment. Alors, pourquoi la présence de l'opérateur d'affectation provoque le compilateur d'identifier ces deux opérations comme étant différent?

Était-ce utile?

La solution

Ceci est parce que vous êtes re-définir un nouveau X. Lorsque vous redéfinissez une constante, il vous donne l'erreur « déjà initialisé ». Le premier exemple ne donne pas cette erreur parce que vous n'êtes pas redéfinir X, vous le modifier.

Autres conseils

Dans Ruby, les variables sont essentiellement des pointeurs vers un lieu dans une mémoire contenant un objet - et non l'objet lui-même. Dans le second exemple, vous initialisez une constante pour pointer vers X un objet dans la première ligne (X = "hello"), et dans la deuxième ligne, vous initialisez à nouveau la constante - mais il pointe déjà à un objet, si vous obtenez l'erreur.

L'immuabilité de Une constante ne signifie pas que vous ne pouvez pas modifier l'objet - cela signifie juste que vous ne pouvez pas changer la constante pour pointer vers autre objet

.

Si vous voulez faire votre constante chaîne « réelle », essayez de « geler »:

X = "foo".freeze        # => "foo" 
X.concat("bar")

TypeError: can't modify frozen string
    from (irb):2:in `concat'
    from (irb):2

Je vous encourage à lire La programmation Ruby languge .

En effet, la constante X stocke une référence à un objet String. Dans votre premier exemple, vous modifiez l'état interne de l'objet concat, mais pas la référence mémorisée par la constante. Dans le deuxième exemple, vous modifiez la référence mémorisée par la constante à un nouvel objet qui est retourné <=> de la méthode <=>.

Le livre Pioche explique cette .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top