Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiline strings with no indent

How do you have a multiline string with no leading spaces and still be properly aligned with method? Here are some of my attempts. The one that is working is not very fun...

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

UPDATE

Here's a 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"
like image 510
binarymason Avatar asked Nov 04 '15 16:11

binarymason


3 Answers

As of Ruby 2.3.0, there is a built in method for this: [<<~]

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

like image 136
Alexander Popov Avatar answered Nov 15 '22 16:11

Alexander Popov


In the RubyTapas Episode 249, Avdi Grimm describes a technique to strip leading whitespace from a multi-line string:

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

It is behavior compatible to other existing solutions to this problem, e.g. String#strip_heredoc in ActiveSupport / Rails or the standalone unindent gem.

You can use this method with a heredoc which is special syntax in ruby (and many other languages) to write multi-line strings.

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
like image 41
Holger Just Avatar answered Nov 15 '22 17:11

Holger Just


You can use a HEREDOC - http://ruby-doc.org/docs/ruby-doc-bundle/Manual/man-1.4/syntax.html#here_doc - like this:

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

and use strip_heredoc to remove the indentations - http://apidock.com/rails/String/strip_heredoc.

NOTE:

strip_heredoc is only available if you're using Ruby on Rails (it's a Rails helper). If you're just building this in pure Ruby, unfortunately strip_heredoc won't be available to you. :-(

But fear not pure Ruby users! You can simply lift the source code for strip_heredoc from Rails and add it to Ruby by re-defining the String class. In which case, you can also call the method whatever you want. :-)

Like so:

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
like image 2
jeffdill2 Avatar answered Nov 15 '22 16:11

jeffdill2