Pourquoi ne pas Ruby ont un réel StringBuffer ou StringIO?
J'ai lu récemment une belle post sur l'utilisation de StringIO
en Ruby. Ce que l'auteur ne mentionne pas, cependant, c'est que StringIO
est juste un "I". Il n'y a pas de "O". Vous ne peut pas de le faire, par exemple:
s = StringIO.new
s << 'foo'
s << 'bar'
s.to_s
# => should be "foo\nbar"
# => really is ''`
Ruby vraiment besoin d'un StringBuffer comme l'a fait la Java. StringBuffers servir deux objectifs importants. Tout d'abord, ils vous permettent de tester la sortie de la moitié de ce que Ruby StringIO n'. Deuxièmement, ils sont utiles pour la construction de longues chaînes de petites pièces -- quelque chose que Joel nous rappelle encore et encore est par ailleurs très très lent.
Est-il une bonne alternative?
Il est vrai que les Chaînes en Ruby sont mutables, mais cela ne signifie pas que nous devons toujours compter sur cette fonctionnalité. Si stuff
est grande, les performances et les besoins en mémoire de cette, par exemple, est très mauvais.
result = stuff.map(&:to_s).join(' ')
La "bonne" façon de le faire en Java:
result = StringBuffer.new("")
for(String s : stuff) {
result.append(s);
}
Bien que mon Java est un peu rouillé.
- "Mega Femme De Ménage?" Jamais entendu parler de lui. Jamais vraiment cru en StringBuffers soit, mais j'ai toujours l'habitude, par peur de quelqu'un, voir mon code. Mais vraiment, est-ce que des trucs jamais ajouter jusqu'à?
- Probablement un "SpaceBalls" référence.
- Mega femme de chambre a été supprimé comme un dommage collatéral de se débarrasser de jurons.
- Votre chaîne de rejoindre exemple n'est pas équivalent au code Java. Comme vous le mentionnez, Ruby chaînes sont mutables, donc en Ruby, vous venez de le faire:
stuff.inject('') { |res, s| res << s.to_s }
. Vous pouvez vous fier sur Ruby cordes mutable, il ne va pas changer comme elle allait se briser à chaque application Ruby dans l'existence. - Je ne comprends vraiment pas pourquoi StringIO ne dispose pas d'une méthode to_s. C'est une classe que de gérer une chaîne de caractères, donc si vous voulez que la chaîne que vous avez à demander spécifiquement pour elle. Il doit avoir une méthode to_s depuis, c'est le rubis de la convention, mais il ne le fait pas. (Quelqu'un peut me corriger si je me trompe)
- En Ruby 3, les littéraux de chaîne serait immuable. Cependant, nous pouvons toujours utiliser mutable
String.new
ou+''
.
Vous devez vous connecter pour publier un commentaire.
J'ai regardé la documentation de ruby pour
StringIO
, et il ressemble à ce que vous voulez, c'estStringIO#string
, pasStringIO#to_s
Ainsi, modifiez votre code pour:
Comme les autres IO-type des objets en Ruby, lorsque vous écrivez à un IO, le pointeur de caractère d'avances.
StringIO#read
, mais je suis toujours un fan de connaître plus d'une façon de faire quelque chose. +1StringIO#string
J'ai fait quelques repères et de l'approche plus rapide est d'utiliser le
String#<<
méthode. À l'aide deStringIO
est un peu plus lent.De la concaténation de chaînes à l'aide de la
String#+
méthode est la plus lente approche par plusieurs ordres de grandeur:Donc je pense que la bonne réponse est que l'équivalent de Java
StringBuffer
est tout simplement à l'aide deString#<<
en Ruby.StringIO
puis sera plus rapideVotre exemple, travaille en Ruby - je l'ai juste essayé.
À moins que je ne me manque que la raison pour laquelle vous êtes à l'aide de to_s - que juste sorties de l'id de l'objet.
Bien, un StringBuffer est pas tout à fait comme nécessaire en Ruby, principalement parce que les Chaînes en Ruby sont mutables... ainsi, vous pouvez construire une chaîne de caractères par la modification de la chaîne existante plutôt que de construire de nouvelles cordes à chaque concat.
Comme une note, vous pouvez également utiliser la chaîne de caractères spéciaux syntaxe où vous pouvez construire une chaîne de caractères qui référence les autres variables à l'intérieur de la chaîne, ce qui le rend très lisible de la chaîne de construction. Considérer:
Ces chaînes peuvent également contenir des expressions, pas seulement les variables... tels que: