在Ruby中的多行中拆分长字符串而不剥离换行符


221

我们最近决定在我的工作中使用红宝石风格指南。命令之一是,任何行都不能超过80个字符。由于这是一个Rails项目,所以我们通常使用的字符串会长一些-即“ 用户X希望向您发送有关Thing Y的消息 ”,但这些字符串并不总是符合80个字符的样式限制。

我了解通过三种方式使长字符串跨越多行:

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

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

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

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

例:

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

我发现以上内容有点难以阅读。

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


您可能需要花些时间来排除那些字符串。
Cheezmeister 2013年


un不清楚是否要保留\n换行符。最佳答案并不能保留它们,而您的答案却可以。这个问题说“不删除换行符”,但是描述中说“ [我必须删除换行符。”
Bryan Dimas

Answers:


432

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

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

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

4
嗯 是的,那非常完美。这实际上是在引擎盖下进行的连接吗?(隐藏+?)
chug2k 2012年

13
我很确定不是这样;我尝试了未定义和重新定义String#+的情况,似乎没有任何内容发送到那里。
杰西兹(Jessehz)2012年

同样,将字符串在同一行上彼此相邻也可以,但这不是很有用。
杰西兹(Jessehz)

3
我也喜欢Emily的解决方案。但是出于某种原因,我对此感到更满意,因为可以缩进以下行中的空白行,而无需进行自我猜测。
阿敏·阿里亚纳

5
重新连接,检查Amadan对这个相关问题的答案。他使用字节码来证明它不是串联字符串,而是将它们视为一个长字符串。
汤姆·洪特

55

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

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

puts string.inspect

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


11
嗯 那很简单。好吧,可能要问的太多了,但我不能缩进下一行。如果可以将其与等号匹配,那将是理想的选择。
chug2k 2012年

5
注意:该反斜杠后不能有空格。它必须是最后一个字符。
朱利安·曼

3
请参阅@Jessehz的答案。具有正确缩进的格式正确的代码的方法是将每一行都用引号引起来。
6

36

三年后,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

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


29
对于任何其他想知道的人:<<~HEREDOC保留换行符,只会消除缩进。例如line 1\nline 2\nline 3\n
Bryan Dimas

1
但是,剥离换行符仍然需要额外的计算,而这并不意味着需要OP。
henrebotha

1
@henrebotha是的,但OP更明确地表示,他们希望“等同于将整个字符串放在一行上”,这将不需要换行符。
尼克,

因此,您在问题中明确指出您不想使用heredoc,而必须删除换行符。您在此处的答案使用Heredoc,并要求您避免使用“后处理”。
拉蒙特

17

当我尝试编写一个非常长的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=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。

在这里,您可以缩进以提高可读性,易于修改,而无需在每行上加上引号和反斜杠。连接琴弦的成本应该可以忽略不计。


10

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

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

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.