283 votes

Découpage de longues chaînes de caractères sur plusieurs lignes en Ruby sans supprimer les retours à la ligne

Nous avons récemment décidé à mon travail d'un guide de style Ruby. L'un des édits est qu'aucune ligne ne doit dépasser 80 caractères. Comme il s'agit d'un projet Rails, nous avons souvent des chaînes de caractères un peu plus longues - par exemple " L'utilisateur X voulait vous envoyer un message à propos de la chose Y. "qui ne respecte pas toujours la limite de 80 caractères.

Je crois savoir qu'il y a trois façons de faire en sorte qu'une longue chaîne s'étende sur plusieurs lignes :

  • HEREDOC
  • %Q{}
  • Concaténation réelle de chaînes de caractères.

Cependant, tous ces cas finissent par prendre plus de cycles de calcul, ce qui semble idiot. La concaténation de chaînes de caractères, évidemment, mais pour HEREDOC et %Q Je dois enlever les nouvelles lignes, via quelque chose comme .gsub(/\n$/, '') .

Existe-t-il une manière syntaxique pure de faire cela, qui soit équivalente au fait d'avoir toute la chaîne sur une seule ligne ? Le but étant, évidemment, de ne pas dépenser de cycles supplémentaires juste parce que je veux que mon code soit légèrement plus lisible. (Oui, je me rends compte que vous devez souvent faire ce compromis... mais pour la longueur des chaînes de caractères, cela semble juste idiot).

Mise à jour : Les antislashs ne sont pas exactement ce que je veux car on perd l'indentation, ce qui affecte vraiment le style/la lisibilité.

Exemple :

if foo
  string = "this is a \  
string that spans lines"  
end

Je trouve ce qui précède un peu difficile à lire.

EDIT : J'ai ajouté une réponse ci-dessous ; trois ans plus tard, nous avons maintenant l'heredoc en forme de squiggly.

0 votes

Cela peut valoir la peine de tenir compte de ces ficelles.

4 votes

2 votes

Ce n'est pas clair si vous voulez garder \n caractères de nouvelle ligne ou non. La première réponse ne les conserve pas, alors que votre réponse les conserve. La question dit "sans supprimer les retours à la ligne", alors que la description dit "[...] je dois supprimer les retours à la ligne".

524voto

Jessehz Points 919

C'est peut-être ce que vous cherchez ?

string = "line #1"\
         "line #2"\
         "line #3"

p string # => "line #1line #2line #3"

4 votes

Huh. ouais, c'est assez parfait. est-ce que c'est en fait une concaténation sous le capot ? (en cachant un + ?)

13 votes

Je suis presque sûr que ce n'est pas le cas ; j'ai essayé d'annuler et de redéfinir String#+ et il ne semble pas que quelque chose soit envoyé ici.

0 votes

Il est également possible de placer les chaînes de caractères les unes à côté des autres sur la même ligne, mais ce n'est pas très utile.

67voto

Emily Points 9231

Vous pouvez utiliser \ pour indiquer qu'une ligne de Ruby continue sur la ligne suivante. Cela fonctionne aussi avec les chaînes de caractères :

string = "this is a \
string that spans lines"

puts string.inspect

produira "this is a string that spans lines"

11 votes

Huh. c'est assez simple. enfin, c'est probablement trop demander, mais je ne peux pas indenter la ligne suivante. ce serait idéal si je pouvais la faire correspondre avec le signe égal.

6 votes

Remarque : il ne peut pas y avoir d'espace blanc après la barre oblique inversée. Il doit être le dernier caractère.

3 votes

Voir la réponse de @Jessehz. La façon d'avoir un code joliment formaté avec une indentation correcte est de mettre chaque ligne entre guillemets.

58voto

chug2k Points 935

Trois ans plus tard, il y a maintenant une solution dans Ruby 2.3 : l'heredoc en forme de vague.

class Subscription
  def warning_message
    <<~HEREDOC
      Subscription expiring soon!
      Your free trial will expire in #{days_until_expiration} days.
      Please update your billing information.
    HEREDOC
  end
end

Lien vers le blog : https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

L'indentation de la ligne la moins indentée sera supprimée de chaque ligne du contenu.

22voto

Zack Xu Points 1531

J'ai eu ce problème lorsque j'ai essayé d'écrire une très longue url, ce qui suit fonctionne.

image_url = %w(
    http://minio.127.0.0.1.xip.io:9000/
    bucket29/docs/b7cfab0e-0119-452c-b262-1b78e3fccf38/
    28ed3774-b234-4de2-9a11-7d657707f79c?
    X-Amz-Algorithm=AWS4-HMAC-SHA256&
    X-Amz-Credential=ABABABABABABABABA
    %2Fus-east-1%2Fs3%2Faws4_request&
    X-Amz-Date=20170702T000940Z&
    X-Amz-Expires=3600&X-Amz-SignedHeaders=host&
    X-Amz-Signature=ABABABABABABABABABABAB
    ABABABABABABABABABABABABABABABABABABA
).join

Notez qu'il ne doit pas y avoir de nouvelles lignes ou d'espaces blancs lorsque la chaîne url est formée. Si vous voulez des nouvelles lignes, utilisez HEREDOC.

Ici, vous avez l'indentation pour la lisibilité, la facilité de modification, sans les guillemets et les antislashes sur chaque ligne. Le coût de la jonction des chaînes de caractères devrait être négligeable.

19voto

iheggie Points 128

J'ai modifié la réponse de Zack puisque je a voulu les espaces et l'interpolation mais pas les nouvelles lignes et utilisé :

%W[
  It's a nice day "#{name}"
  for a walk!
].join(' ')

name = 'fred' cela produit It's a nice day "fred" for a walk!

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