没有缩进的多行字符串

Multiline strings with no indent

如何让多行字符串在没有前导空格的情况下仍然与方法正确对齐?这是我的一些尝试。正在工作的那个不是很好玩...

module Something
  def welcome
"
Hello

This is an example.  I have to write this multiline string outside the welcome method
indentation in order for it to be properly formatted on screen. :(
"
  end
end

module Something
  def welcome
    "
    Hello

    This is an example.  I am inside welcome method indentation but for some reason
    I am not working...
    ".ljust(12)
  end
end

module Something
  def welcome
    "Hello\n\n"+
    "This is an example.  I am inside welcome method indentation and properly"+
    "formatted but isn't there a better way?"
  end
end

更新

这里是 method from the ruby style guide:

code = <<-END.gsub(/^\s+\|/, '')
  |def test
  |  some_method
  |  other_method
  |end
END
# => "def test\n  some_method\n  other_method\nend\n"

您可以使用 HEREDOC - http://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html#here_doc - 像这样:

def welcome
  <<-"welcome".strip_heredoc
    "
    Hello

    This is an example.  I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(
    "
  welcome
end

并使用 strip_heredoc 删除缩进 - http://apidock.com/rails/String/strip_heredoc.

注意:

strip_heredoc 仅当您在 Rails 上使用 Ruby 时可用(它是 Rails 助手)。如果您只是在纯 Ruby 中构建它,很遗憾,您将无法使用 strip_heredoc。 :-(

但怕不是纯Ruby用户!您可以简单地从 Rails 中提取 strip_heredoc 的源代码,并通过重新定义 String class 将其添加到 Ruby。在这种情况下,您也可以随意调用该方法。 :-)

像这样:

class String
  def strip_it_real_good
    indent = scan(/^[ \t]*(?=\S)/).min.try(:size) || 0
    gsub(/^[ \t]{#{indent}}/, '')
  end
end

def welcome
  <<-"welcome".strip_it_real_good
    "
    Hello

    This is an example.  I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(
    "
  welcome
end

我不确定我是否理解问题。这个(纯 Ruby)解决方案能满足您的需求吗?

arr = <<-BITTER_END.split("\n")
  Hello
         Testing, testing.
       I assume the least-indented line is to be left-adjusted and the same amount of leading whitespace is to be removed from all other lines.
BITTER_END
undent = arr.map { |line| line[/^\s*/].size }.min
str = arr.map { |s| s[undent..-1] }.join("\n")

puts str
Hello
     Testing, testing.
   I assume the least-indented line is to be left-adjusted and the same amount of leading whitespace is to be removed from all other lines.

RubyTapas Episode 249 中,Avdi Grimm 描述了一种从多行字符串中去除前导空格的技术:

def unindent(s)
  s.gsub(/^#{s.scan(/^[ \t]+(?=\S)/).min}/, '')
end

它在行为上与此问题的其他现有解决方案兼容,例如String#strip_heredoc in ActiveSupport / Rails or the standalone unindent gem.

您可以将此方法与 heredoc 结合使用,这是 ruby(以及许多其他语言)中的特殊语法,用于编写多行字符串。

module Something
  def unindent(s)
    s.gsub(/^#{s.scan(/^[ \t]+(?=\S)/).min}/, '')
  end

  def welcome
    unindent(<<-TEXT)
      Hello

      This is an example. This multiline string works
        - even with deeper nestings...
      All is OK here :)
    TEXT
  end
end

从 Ruby 2.3.0 开始,有一个内置方法:[<<~]

indented = 
<<-EOS
  Hello

  This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(
EOS

unindented =
<<~EOS
  Hello

  This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(
EOS

puts indented #=>

  Hello

  This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(

puts unindented #=>

Hello

This is an example. I have to write this multiline string outside the welcome method indentation in order for it to be properly formatted on screen. :(

Multiline strings in Ruby 2.3 - the squiggly heredoc