265

我们最近决定在我的工作中编写一份 ruby​​ 风格指南。其中一项法令是任何行不得超过 80 个字符。由于这是一个 Rails 项目,我们经常有一些较长的字符串——例如“用户 X 想给你发送一条关于事物 Y 的消息”,它并不总是符合 80 个字符的样式限制。

我知道有三种方法可以使长字符串跨越多行:

  • 赫雷多克
  • %Q{}
  • 实际的字符串连接。

然而,所有这些情况最终都会花费更多的计算周期,这似乎很愚蠢。字符串连接很明显,但是HEREDOC%Q必须通过类似.gsub(/\n$/, '').

有没有一种纯粹的语法方式来做到这一点,这相当于将整个字符串放在一行上?显然,目标是不要仅仅因为我希望我的代码更具可读性而花费任何额外的周期。(是的,我意识到你必须做出很多权衡......但是对于字符串长度,这似乎很愚蠢。)

更新:反斜杠不是我想要的,因为你失去了缩进,这真的影响了风格/可读性。

例子:

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

我觉得上面的内容有点难以阅读。

编辑:我在下面添加了一个答案;三年后,我们现在有了波浪形的heredoc。

4

8 回答 8

503

也许这就是你要找的东西?

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

p string # => "line #1line #2line #3"
于 2012-05-09T21:10:20.643 回答
65

您可以使用\表示任何 Ruby 行在下一行继续。这也适用于字符串:

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

puts string.inspect

将输出"this is a string that spans lines"

于 2012-05-09T19:01:53.190 回答
56

三年后,现在在 Ruby 2.3 中有一个解决方案:波浪形的heredoc。

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

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

缩进最小的行的缩进将从内容的每一行中删除。

于 2016-10-03T08:57:09.337 回答
22

当我尝试写一个很长的网址时,我遇到了这个问题,下面的作品。

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

注意,形成 url 字符串时不能有任何换行符、空格。如果您想要换行符,请使用 HEREDOC。

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

于 2017-07-07T10:31:51.053 回答
18

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

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

这在哪里name = 'fred'产生It's a nice day "fred" for a walk!

于 2017-08-18T12:48:10.580 回答
12

到目前为止,这是一个非常古老的问题,但由于问题似乎仍然出现,这里有一个更新的答案。由于原始海报表明这是针对 Rails 项目的,因此您可以查看 Rails 的 String inflections 寻求帮助。

my_long_string = <<-STRING
 hello
    there
 multiline
      multiindented string
STRING

=> " hello\n    there\n multiline\n      multiindented string\n"

输入squish方法。

my_long_string = <<-STRING.squish
 so
    long
 multiline
      multiindented string
STRING

=> "so long multiline multiindented string"

根据文档 -

squish() 返回字符串,首先删除字符串两端的所有空格,然后将剩余的连续空格组更改为每个空格。

于 2021-05-21T19:28:32.720 回答
1

Rails 中的 Squish 可以满足您的需求。

https://apidock.com/rails/String/squish

结束它看起来像这样:

%{ Multi-line
   string }.squish

因为你在 Ruby 中需要它,所以看看 Rails 代码:

%{ Multi-line
   string }
  .gsub!(/[[:space:]]+/, " ")
  .strip!
于 2021-09-24T07:12:15.653 回答
0

您可以连接多个拆分为多行的字符串:

if foo
  string = "this is a" + 
           "string that spans lines"  
end
于 2021-04-19T23:48:02.580 回答