43 votes

Pourquoi Matz a-t-il choisi de rendre les chaînes mutables par défaut en Ruby?

C'est l'inverse de cette question: http://stackoverflow.com/questions/93091/why-cant-strings-be-mutable-in-java-and-net

Ce choix a été fait en Ruby seulement en raison de l'exploitation (ajoute et tel) sont efficaces sur les cordes mutables, ou y avait-il une autre raison?

(Si c'est seulement de l'efficacité, qui semble étrange, depuis la conception de Ruby semble contraire à ne pas mettre une prime élevée sur faciliating la mise en œuvre efficace.)

32voto

rjh Points 17192

Ceci est en ligne avec les Rubis de la conception, comme vous le notez. Les cordes immuables sont plus efficaces que les cordes mutables - moins de la copie, comme les chaînes de caractères sont ré-utilisés - mais rendre le travail plus difficile pour le programmeur. Il est intuitif de voir les chaînes de caractères comme mutable - vous pouvez concaténer ensemble. Pour faire face à cela, Java silencieusement se traduit par concaténation (via +) des deux chaînes dans l'utilisation d'un objet StringBuffer, et je suis sûr qu'il ya d'autres hacks. Ruby choisit plutôt de faire des chaînes de mutables par défaut au détriment des performances.

Ruby a également un certain nombre de méthodes de destruction tels que String#upcase! qui s'appuient sur les cordes mutable.

Une autre raison possible est que Ruby est inspiré par Perl, Perl et arrive à utiliser les cordes mutables.

Ruby a des Symboles et surgelés, les Cordes, les deux sont immuables. Comme un bonus supplémentaire, les symboles sont garantis d'être unique par possible de la chaîne de valeur.

5voto

Kelvin Points 5810

Ce sont mes opinions, pas du Matz. Pour les fins de cette réponse, quand je dis qu'une langue est "immuable chaînes", cela signifie que tous ses cordes sont immuables, c'est à dire il n'y a aucun moyen de créer une chaîne de caractères qui est mutable.

  1. Le "immuable" chaîne de conception voit les chaînes de caractères comme les deux identifiants (comme par exemple les clés de hachage et d'autres VM-usages internes) et de stockage de données des structures. L'idée est que c'est dangereux pour les identificateurs mutable. Pour moi, cela sonne comme une violation de la seule responsabilité. En Ruby, nous avons symbole pour les identificateurs, de sorte que les chaînes sont libres d'agir comme des banques de données. C'est vrai que Ruby permet de chaînes que les clés de hachage, mais je pense que c'est rare pour un programmeur pour stocker une chaîne de caractères dans une variable, l'utiliser comme une clé de hachage, puis modifier la chaîne. Dans le programmeur de l'esprit, il est (ou devrait être) une séparation de 2 usages de chaînes de caractères. Souvent, une chaîne utilisée comme une clé de hachage est une chaîne littérale, donc il y a peu de chances d'être muté. À l'aide d'une chaîne de caractères comme une clé de hachage n'est pas très différente de l'utilisation d'un tableau de deux chaînes de caractères en une clé de hachage. Aussi longtemps que votre esprit a une bonne compréhension de ce que vous êtes en utilisant, comme une clé, alors il n'y a pas de problème.

  2. Avoir une chaîne de données magasin est utile d'un point de vue cognitif de la simplicité. Il suffit de considérer Java et de ses StringBuffer. C'est une structure de données supplémentaires (dans une déjà grande et souvent peu intuitive de la bibliothèque standard) que vous avez à gérer si vous essayez de faire les opérations de la chaîne, comme l'insertion d'une chaîne de caractères à un certain indice d'une autre chaîne. Donc, d'un côté, Java reconnaît le besoin de faire ces sortes d'opérations, mais parce que les cordes immuables sont exposés pour le programmeur, ils ont dû introduire une autre structure, de sorte que les opérations sont toujours possible sans faire de nous réinventer la roue. Cela augmente la charge cognitive sur le programmeur.

  3. En Python, il semble que la façon la plus simple pour insérer est de saisir les sous-chaînes avant et après le point d'insertion, puis de les enchaîner autour de la pour être inséré chaîne. Je suppose qu'ils pourraient facilement ajouter une méthode à la bibliothèque standard, qui insère et renvoie une nouvelle chaîne. Cependant, si la méthode est appelée insert, les débutants peuvent penser que c'mutation de la chaîne; à être descriptive, il aurait du s'appeler new_with_inserted ou quelque chose de bizarre comme ça. En utilisation de tous les jours, "insertion" ce qui signifie que vous changez le contenu de la les choses inséré dans (par exemple, l'insertion d'une enveloppe dans une boîte aux lettres de change le contenu de la boîte aux lettres). Encore une fois, cela soulève la question, "pourquoi ne puis-je changer mon magasin de données?"

  4. Ruby prévoit le gel des objets, de sorte qu'ils peuvent sans danger être passé autour sans introduire des bogues subtils. La bonne chose est que Ruby traite des chaînes de caractères comme toute autre structure de données (tableaux, tables de hachage, les instances de classe); ils peuvent être congelés. La cohérence est le programmeur de l'environnement. Les cordes immuables faire des chaînes de se démarquer comme un "spécial" structure de données, lorsqu'il n'est pas vraiment, si vous l'utilisez comme une banque de données.

1voto

Kamil Tomšík Points 1181

Je pense que c'est parce que cela facilite certaines choses, comme par exemple le remplacement de sous-chaînes:

 hello = "Hello World."
hello["."] = "!!!"
 

Sans les chaînes étant mutables, ce serait beaucoup plus long.

Et ce serait encore pire, si cette chaîne avait une structure plus profonde (oui cela ne devrait pas arriver mais parfois ça arrive):

 someGroup.subGroup.hello["."] = "!!!"
 

Imaginez à quel point cela serait verbeux sans un tel sucre de syntaxe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X