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

C’est l’inverse de cette question: pourquoi les chaînes ne peuvent-elles pas être mutées en Java et en .NET?

Ce choix a-t-il été fait dans Ruby uniquement parce que les opérations (annexes et autres) sont efficaces sur les chaînes modifiables, ou y avait-il une autre raison?

(Si ce n’est que de l’efficience, cela semblerait étrange, car la conception de Ruby semble autrement ne pas mettre l’accent sur la facilitation d’une mise en œuvre efficace.)

Ceci est conforme au design de Ruby, comme vous le notez. Les chaînes immuables sont plus efficaces que les chaînes modifiables – moins de copie, car les chaînes sont réutilisées – mais rendent le travail plus difficile pour le programmeur. Il est intuitif de voir les chaînes comme mutables – vous pouvez les concaténer ensemble. Pour faire face à cela, Java traduit silencieusement la concaténation (via + ) de deux chaînes en un object SsortingngBuffer, et je suis sûr qu’il existe d’autres hacks de ce type. Ruby choisit plutôt de rendre les chaînes modifiables par défaut au désortingment des performances.

Ruby a également un certain nombre de méthodes destructives telles que Ssortingng#upcase! qui s’appuient sur des chaînes mutables.

Une autre raison possible est que Ruby s’inspire de Perl et que Perl utilise des chaînes mutables.

Ruby a des symboles et des chaînes gelées, les deux sont immuables. En prime, les symboles sont garantis uniques par valeur de chaîne possible.

Ce sont mes opinions, pas celles de Matz. Pour répondre à cette question, lorsque je dis qu’un langage a des “chaînes immuables”, cela signifie que toutes ses chaînes sont immuables, c’est-à-dire qu’il n’ya aucun moyen de créer une chaîne mutable.

  1. La conception “chaîne immuable” considère les chaînes comme des identificateurs (par exemple, des clés de hachage et autres utilisations internes à la machine virtuelle) et des structures de stockage de données . L’idée est qu’il est dangereux que les identifiants soient mutables. Pour moi, cela ressemble à une violation de responsabilité unique. Dans Ruby, nous avons un symbole pour les identifiants, donc les chaînes sont libres d’agir comme des magasins de données. Il est vrai que Ruby autorise les chaînes de caractères comme clés de hachage, mais je pense qu’il est rare qu’un programmeur enregistre une chaîne dans une variable, l’utilise comme clé de hachage, puis modifie la chaîne. Dans l’esprit du programmeur, il existe (ou devrait être) une séparation de 2 utilisations de chaînes. Souvent, une chaîne utilisée comme clé de hachage est une chaîne littérale, il y a donc peu de chances qu’elle soit mutée. L’utilisation d’une chaîne en tant que clé de hachage n’est pas très différente de l’utilisation d’un tableau de deux chaînes en tant que clé de hachage. Tant que votre esprit comprend bien ce que vous utilisez comme clé, il n’y a pas de problème.

  2. Avoir une chaîne en tant que magasin de données est utile du sharepoint vue de la simplicité cognitive. Considérons juste Java et son SsortingngBuffer . Il s’agit d’une structure de données supplémentaire (dans une bibliothèque standard déjà volumineuse et souvent peu intuitive) que vous devez gérer si vous essayez d’effectuer des opérations de chaîne telles que l’insertion d’une chaîne à un certain index d’une autre chaîne. Donc, d’une part, Java reconnaît la nécessité de faire ce genre d’opérations, mais comme les chaînes immuables sont exposées au programmeur, elles ont dû introduire une autre structure pour que les opérations soient toujours possibles sans nous obliger à réinventer la roue. Cela met une charge cognitive supplémentaire sur le programmeur.

  3. En Python, il semble que le moyen le plus simple d’insérer soit de saisir les sous-chaînes avant et après le point d’insertion, puis de les concaténer autour de la chaîne à insérer. Je suppose qu’ils pourraient facilement append une méthode à la bibliothèque standard qui insère et renvoie une nouvelle chaîne. Cependant, si la méthode s’appelle insert , les débutants peuvent penser qu’elle mute la chaîne; pour être descriptif, il faudrait l’appeler new_with_inserted ou quelque chose de bizarre comme ça. Dans l’utilisation quotidienne, “insérer” signifie que vous modifiez le contenu des éléments insérés (par exemple, l’insertion d’une enveloppe dans une boîte aux lettres modifie le contenu de la boîte aux lettres). Encore une fois, cela soulève la question “pourquoi ne puis-je pas modifier mon magasin de données?”

  4. Ruby permet de geler les objects afin qu’ils puissent circuler en toute sécurité sans introduire de bogues subtils. Ce qui est bien, c’est que Ruby traite les chaînes comme n’importe quelle autre structure de données (tableaux, hachages, instances de classes); ils peuvent tous être congelés. La cohérence est conviviale pour les programmeurs. Les chaînes immuables font ressortir les chaînes comme une structure de données “spéciale”, quand ce n’est pas vraiment le cas, si vous l’utilisez comme magasin de données.