在Ruby中,在多行中分割长字符串,而不剥离新行

时间:2022-03-07 01:48:24

We recently decided at my job to a ruby style guide. One of the edicts is that no line should be wider than 80 characters. Since this is a Rails project, we often have strings that are a little bit longer - i.e. "User X wanted to send you a message about Thing Y" that doesn't always fit within the 80 character style limit.

我们最近决定在我的工作中采用ruby风格的指南。其中一条规则是,任何一行都不能超过80个字符。由于这是一个Rails项目,我们经常会有稍微长一点的字符串—例如。“用户X想给你发送一个关于Y的消息”,这并不总是符合80字符样式的限制。

I understand there are three ways to have a long string span multiple lines:

我知道有三种方法可以让长串跨多行:

  • HEREDOC
  • HEREDOC
  • %Q{}
  • Q % { }
  • Actual string concatenation.
  • 实际的字符串连接。

However, all of these cases end up taking more computation cycles, which seems silly. String concatenation obviously, but for HEREDOC and %Q I have to strip out the newlines, via something like .gsub(/\n$/, '').

然而,所有这些情况最终都需要花费更多的计算周期,这似乎很愚蠢。显然是字符串连接,但是对于赫里多克和%Q,我必须通过.gsub(/\n$/,”)之类的方式去掉换行符。

Is there a pure syntax way to do this, that is equivalent to just having the whole string on one line? The goal being, obviously, to not spend any extra cycles just because I want my code to be slightly more readable. (Yes, I realize that you have to make that tradeoff a lot...but for string length, this just seems silly.)

是否有一种纯粹的语法方法可以做到这一点,那就等于把整个字符串放在一行上?很明显,我们的目标是,不要仅仅因为我想让我的代码更具可读性而花费额外的周期。(是的,我知道你必须做很多权衡……)但是对于字符串长度,这看起来很傻。

Update: Backslashes aren't exactly what I want because you lose indentation, which really affects style/readability.

更新:反斜杠并不是我想要的,因为您丢失了缩进,这确实影响了样式/可读性。

Example:

例子:

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

I find the above a bit hard to read.

我发现上面有点难读。

EDIT: I added an answer below; three years later we now have the squiggly heredoc.

编辑:我在下面添加了一个答案;三年后,我们有了这个弯曲的赫里多克。

5 个解决方案

#1


339  

Maybe this is what you're looking for?

也许这就是你要找的?

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

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

#2


45  

You can use \ to indicate that any line of Ruby continues on the next line. This works with strings too:

您可以使用\来指示下一行的Ruby继续运行。这也适用于字符串:

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

puts string.inspect

will output "this is a string that spans lines"

输出"这是一个跨线的字符串"

#3


27  

Three years later, there is now a solution in Ruby 2.3: The squiggly heredoc.

三年后,Ruby 2.3中出现了一个解决方案:弯曲的赫里多克。

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

Blog post link: https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

博客文章链接:https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

The indentation of the least-indented line will be removed from each line of the content.

在内容的每一行都将删除最小缩进行的缩进。

#4


8  

I had this problem when I try to write a very long url, the following works.

当我尝试写一个很长的url时,我遇到了这个问题。

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=AJAKJFAFGAKAJDDAF
    %2Fus-east-1%2Fs3%2Faws4_request&
    X-Amz-Date=20170702T000940Z&
    X-Amz-Expires=3600&X-Amz-SignedHeaders=host&
    X-Amz-Signature=QEWKJRQJEWR813247812347FKFS
    KQWREJQ3108418324732o45o1324kldsfjasf
).join

Note, there must not be any newlines, white spaces when the url string is formed. If you want newlines, then use HEREDOC.

注意,在形成url字符串时,不能有任何新行和空格。如果你想要换行,可以使用赫里多克。

Here you have indentation for readability, ease of modification, without the fiddly quotes and backslashes on every line. The cost of joining the strings should be negligible.

这里有缩进的可读性,易于修改,没有繁琐的引号和反斜杠在每一行。加入字符串的成本应该可以忽略不计。

#5


5  

I modified Zack's answer since I wanted spaces and interpolation but not newlines and used:

我修改了Zack的答案,因为我想要空格和插值,但不是换行和使用:

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

where name = 'fred' this produces It's a nice day "fred" for a walk!

在哪里名字= '弗雷德'这产生了一个美好的一天"弗雷德"散步!

#1


339  

Maybe this is what you're looking for?

也许这就是你要找的?

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

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

#2


45  

You can use \ to indicate that any line of Ruby continues on the next line. This works with strings too:

您可以使用\来指示下一行的Ruby继续运行。这也适用于字符串:

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

puts string.inspect

will output "this is a string that spans lines"

输出"这是一个跨线的字符串"

#3


27  

Three years later, there is now a solution in Ruby 2.3: The squiggly heredoc.

三年后,Ruby 2.3中出现了一个解决方案:弯曲的赫里多克。

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

Blog post link: https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

博客文章链接:https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredoc

The indentation of the least-indented line will be removed from each line of the content.

在内容的每一行都将删除最小缩进行的缩进。

#4


8  

I had this problem when I try to write a very long url, the following works.

当我尝试写一个很长的url时,我遇到了这个问题。

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=AJAKJFAFGAKAJDDAF
    %2Fus-east-1%2Fs3%2Faws4_request&
    X-Amz-Date=20170702T000940Z&
    X-Amz-Expires=3600&X-Amz-SignedHeaders=host&
    X-Amz-Signature=QEWKJRQJEWR813247812347FKFS
    KQWREJQ3108418324732o45o1324kldsfjasf
).join

Note, there must not be any newlines, white spaces when the url string is formed. If you want newlines, then use HEREDOC.

注意,在形成url字符串时,不能有任何新行和空格。如果你想要换行,可以使用赫里多克。

Here you have indentation for readability, ease of modification, without the fiddly quotes and backslashes on every line. The cost of joining the strings should be negligible.

这里有缩进的可读性,易于修改,没有繁琐的引号和反斜杠在每一行。加入字符串的成本应该可以忽略不计。

#5


5  

I modified Zack's answer since I wanted spaces and interpolation but not newlines and used:

我修改了Zack的答案,因为我想要空格和插值,但不是换行和使用:

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

where name = 'fred' this produces It's a nice day "fred" for a walk!

在哪里名字= '弗雷德'这产生了一个美好的一天"弗雷德"散步!