带多行缩进的字符串插值

时间:2018-08-29 09:25:24

标签: ruby string indentation string-interpolation heredoc

给出多行字符串:

body = "\
{
  {
    foo
  }
}"

我想要一种简单的方法将其嵌入到较大的字符串中,并在每行上都使用缩进,以便得到这样的字符串:

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

其中子字符串body应该被插值两次。

这样做:

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

产生:

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

这很有意义,但不是我想要的。我可以编写代码以生成期望的代码,但是代码要好得多。

是否有一种很好的方法来保持#{}字符串插值的优美性并获得缩进?

2 个答案:

答案 0 :(得分:2)

它完美保留了缩进。在第二个开口卷曲之前,您的身体有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
#        }
#      }
#    }
#  }

答案 1 :(得分:2)

并非完全符合您的要求,但是假设您使用ActiveSupport,则会在可读性和实现简单性之间做出很好的折衷:

body = "\
{
  {
    foo
  }
}"

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