【问题标题】:String interpolation with multiline indentation带多行缩进的字符串插值
【发布时间】:2019-02-04 00:55:31
【问题描述】:

给定一个多行字符串:

body = "\
{
  {
    foo
  }
}"

我想要一种简单的方法来将它嵌入到一个更大的字符串中,并对其每一行都应用缩进,这样我就可以得到一个这样的字符串:

{
  {
    {
      {
        foo
      }
    }
    {
      {
        foo
      }
    }
  }
}

子串body应该被插值两次。

这样做:

puts "\
{
  {
    #{body}
    #{body}
  }
}
"

产生:

{
  {
    {
  {
    foo
  }
}
    {
  {
    foo
  }
}
  }
}

这是有道理的,但不是我想要的。我可以编写代码来生成我所期望的,但代码要好得多。

有没有很好的方法来保持#{}字符串插值的优雅并获得缩进?

【问题讨论】:

  • 首先,您可能希望使用HEREDOC 而不是那个多行字符串。其次,正如你所说,ruby 的行为在这里完全有意义——它的表现完全符合人们的预期。第三,对于复杂的数据结构,像这样笨拙地手动生成优雅的空白并不常见……这可能是 XY 问题吗?例如,也许您可​​以使用 JSON.pretty_generate 之类的东西来为您完成所有艰苦的工作?
  • 参考@TomLords HEREDOC
  • 看起来你正在构建一个漂亮的打印版本的数据结构。在我看来,您的示例只是一个简化的 JSON。那是你想要做的吗?您是否考虑过使用 JSON.pretty_generate 之类的东西?
  • 一些 cmets 和答案似乎没有考虑到我在问题中写的所有内容。 Ruby 的回答是正确的,当然它保留了我的#{...} 之前的字符,这显然不是我的问题。我不想生成 JSON 或 HTML,或者之后使用后处理工具。我知道 heredocs,我并没有试图通过使用与问题无关的所有花里胡哨来炫耀。

标签: ruby string indentation string-interpolation heredoc


【解决方案1】:

它完美地保留了缩进。你的身体在第二个开卷曲之前有 2 个空格。为什么你会期望它知道它在两个已经打开的卷曲中并且应该神奇地添加一些缩进?

不过,您可以使用自己的压头:

 indent = ->(anything, level = 0, indenter = "  ") do
   anything.split($/).map.with_index do |line, idx|
     next line if idx.zero?
     line.prepend(indenter * level)
   end.join($/)
 end

 body = "\
 {
   {
     foo
   }
 }"

 puts "\
 {
   {
     #{indent.(body, 2)}
     #{indent.(body, 2)}
   }
 }"

#⇒ {
#    {
#      {
#        {
#          foo
#        }
#      }
#      {
#        {
#          foo
#        }
#      }
#    }
#  }

【讨论】:

  • “你为什么希望它 [...] 神奇地添加一些缩进?” – 因为它是 Ruby ?
  • @Stefan 有时我讨厌这种几乎所有现代语言都会带给我们的“一切都会自动为你完成”的感觉。
  • “你为什么希望它知道它在两个已经打开的卷曲中,并且应该神奇地添加一些缩进?”我当然没有……你真的认为有人会问这样的问题吗?您可能已经注意到 #{body} 是缩进的;这就是我想要保留的。
  • 并且您将正文内容的第一行缩进。尽管如此,要知道如何缩进可能有换行符的整个内容,引擎应该向后看直到行首,我猜这首先会大大减慢插值。
【解决方案2】:

不完全是你想要的,但是在可读性和实现简单性之间的一个很好的折衷,假设你使用 ActiveSupport:

body = "\
{
  {
    foo
  }
}"

puts "\
{
  {
#{body.indent(4)}
#{body.indent(4)}
  }
}
"

【讨论】:

  • 谢谢,我不知道这个功能!但我也没有使用 ActiveSupport。
猜你喜欢
  • 1970-01-01
  • 2016-11-25
  • 2013-04-08
  • 2016-02-05
  • 2011-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多