首页 > 解决方案 > 带多行缩进的字符串插值

问题描述

给定一个多行字符串:

body = "\
{
  {
    foo
  }
}"

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

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

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

这样做:

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

产生:

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

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

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

标签: rubystringindentationstring-interpolationheredoc

解决方案


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

推荐阅读