Je recherche une manière plus élégante de concaténer des cordes en Ruby.
J'ai la ligne suivante:
source = "#{ROOT_DIR}/" << project << "/App.config"
Existe-t-il une meilleure façon de procéder?
Et d'ailleurs, quelle est la différence entre <<
et +
?
ruby
string-concatenation
dagda1
la source
la source
Réponses:
Vous pouvez le faire de plusieurs manières:
<<
mais ce n'est pas la manière habituelleAvec interpolation de chaîne
avec
+
La deuxième méthode semble être plus efficace en termes de mémoire / vitesse par rapport à ce que j'ai vu (non mesuré cependant). Les trois méthodes génèrent une erreur constante non initialisée lorsque ROOT_DIR est nul.
Lorsque vous traitez des noms de chemin, vous pouvez utiliser
File.join
pour éviter de gâcher le séparateur de nom de chemin.Au final, c'est une question de goût.
la source
le
+
opérateur est le choix de concaténation normal et est probablement le moyen le plus rapide de concaténer des chaînes.La différence entre
+
et<<
est que<<
change l'objet sur son côté gauche, et+
ne change pas.la source
+
et<<
seront à peu près les mêmes. Si vous avez affaire à beaucoup de chaînes ou à de très grosses chaînes, vous remarquerez peut-être une différence. J'ai été surpris par la similitude de leurs performances. gist.github.com/28953115.times do ... end
bloc) pour chaque interprète, vous vous retrouveriez avec des résultats plus précis. Mes tests ont montré que l'interpolation est la méthode la plus rapide, sur tous les interprètes Ruby. Je m'attendais<<
à être le plus rapide, mais c'est pourquoi nous nous référons.Si vous ne faites que concaténer des chemins, vous pouvez utiliser la méthode File.join de Ruby.
la source
depuis http://greyblake.com/blog/2012/09/02/ruby-perfomance-tricks/
Utiliser
<<
akaconcat
est beaucoup plus efficace que+=
, car ce dernier crée un objet temporel et remplace le premier objet par le nouvel objet.production:
la source
Étant donné que c'est un chemin, j'utiliserais probablement un tableau et une jointure:
la source
Voici une autre référence inspirée de cet essentiel . Il compare la concaténation (
+
), l'ajout (<<
) et l'interpolation (#{}
) pour les chaînes dynamiques et prédéfinies.production:
Conclusion: l'interpolation en IRM est lourde.
la source
Je préfère utiliser Pathname:
sur
<<
et à+
partir de ruby docs:+
: Renvoie une nouvelle chaîne contenant other_str concaténée à str<<
: Concatène l'objet donné à str. Si l'objet est un Fixnum compris entre 0 et 255, il est converti en caractère avant la concaténation.donc la différence est dans ce qui devient le premier opérande (
<<
fait des changements sur place,+
retourne une nouvelle chaîne donc c'est de la mémoire plus lourde) et ce qui sera si le premier opérande est Fixnum (<<
ajoutera comme s'il s'agissait d'un caractère avec un code égal à ce nombre,+
augmentera Erreur)la source
Pathname('/home/foo') + '/etc/passwd' # => #<Pathname:/etc/passwd>
. Ceci est de par leur conception, basé sur l'exemple rubydoc. Semble que File.join est plus sûr.(Pathname(ROOT_DIR) + project + 'App.config').to_s
si vous souhaitez renvoyer un objet chaîne.Permettez-moi de vous montrer toute mon expérience avec cela.
J'ai eu une requête qui a retourné 32k d'enregistrements, pour chaque enregistrement, j'ai appelé une méthode pour formater cet enregistrement de base de données dans une chaîne formatée et ensuite la concaténer en une chaîne qui, à la fin de tout ce processus, se transformera en un fichier sur le disque.
Mon problème était que d'après le dossier, vers 24k, le processus de concaténation de la chaîne s'est avéré douloureux.
Je faisais cela en utilisant l'opérateur "+" normal.
Quand je suis passé au «<<», c'était comme par magie. C'était vraiment rapide.
Donc, je me suis souvenu de mes vieux temps - en quelque sorte 1998 - quand j'utilisais Java et concaténais String en utilisant '+' et que je passais de String à StringBuffer (et maintenant nous, développeur Java, avons StringBuilder).
Je crois que le processus de + / << dans le monde Ruby est le même que + / StringBuilder.append dans le monde Java.
Le premier réalloue l'objet entier en mémoire et l'autre pointe simplement vers une nouvelle adresse.
la source
Concaténation vous dites? Et la
#concat
méthode alors?En toute équité,
concat
est alias comme<<
.la source
"foo" "bar" 'baz" #=> "foobarabaz"
Voici d'autres façons de procéder:
Etc ...
la source
Vous pouvez également utiliser
%
comme suit:Cette approche fonctionne également avec les
'
guillemets (simples).la source
Vous pouvez utiliser
+
ou<<
opérateur, mais dans la.concat
fonction rubis est la plus préférable, car elle est beaucoup plus rapide que les autres opérateurs. Vous pouvez l'utiliser comme.la source
.
après votre dernierconcat
non?La situation est importante, par exemple:
Dans le premier exemple, la concaténation avec l'
+
opérateur ne mettra pas à jour l'output
objet, cependant, dans le deuxième exemple, l'<<
opérateur mettra à jour l'output
objet à chaque itération. Donc, pour le type de situation ci-dessus,<<
c'est mieux.la source
Vous pouvez concaténer directement dans la définition de chaîne:
la source
Pour votre cas particulier, vous pouvez également utiliser
Array#join
lors de la construction du type de chaîne de chemin de fichier:Cela a un effet secondaire agréable de convertir automatiquement différents types en chaîne:
la source
Pour les marionnettes:
la source