Is there an easy way to do multiline indented strings in Ruby?
Since Ruby 2.3, the <<~
heredoc strips leading content whitespace:
def make_doc(body)
<<~EOF
<html>
<body>
#{body}
</body>
</html>
EOF
end
puts make_doc('hello')
For older Ruby versions, the following is more verbose than the solutions presented in the other answers, but there's almost no performance overhead.It's about as fast as a single long string literal:
def make_doc(body)
"<html>\n" \
" <body>\n" \
" #{body}\n" \
" </body>\n" \
"</html>"
end
Ruby: Can I write multi-line string with no concatenation?
There are pieces to this answer that helped me get what I needed (easy multi-line concatenation WITHOUT extra whitespace), but since none of the actual answers had it, I'm compiling them here:
str = 'this is a multi-line string'\
' using implicit concatenation'\
' to prevent spare \n\'s'
=> "this is a multi-line string using implicit concatenation to eliminate spare
\\n's"
As a bonus, here's a version using funny HEREDOC syntax (via this link):p <<END_SQL.gsub(/\s+/, " ").strip
SELECT * FROM users
ORDER BY users.id DESC
END_SQL
# >> "SELECT * FROM users ORDER BY users.id DESC"
The latter would mostly be for situations that required more flexibility in the processing. I personally don't like it, it puts the processing in a weird place w.r.t. the string (i.e., in front of it, but using instance methods that usually come afterward), but it's there. Note that if you are indenting the last END_SQL
identifier (which is common, since this is probably inside a function or module), you will need to use the hyphenated syntax (that is, p <<-END_SQL
instead of p <<END_SQL
). Otherwise, the indenting whitespace causes the identifier to be interpreted as a continuation of the string.This doesn't save much typing, but it looks nicer than using + signs, to me.
Also (I say in an edit, several years later), if you're using Ruby 2.3+, the operator <<~ is also available, which removes extra indentation from the final string. You should be able to remove the .gsub
invocation, in that case (although it might depend on both the starting indentation and your final needs).
EDIT: Adding one more:
p %{
SELECT * FROM users
ORDER BY users.id DESC
}.gsub(/\s+/, " ").strip
# >> "SELECT * FROM users ORDER BY users.id DESC"
Interpolate multiline string with correct indent
I woke up and saw this question and decided to make it a morning programming puzzle to solve. It was harder than I thought. I'm not thrilled with the API or the complexity, but I didn't want to spend any more time, and it does work. Maybe you'll find it useful. If not, perhaps it will at least inspire some other alternative approaches.
I do not know of any libraries or frameworks that meet your needs using plain Ruby Here Documents. Ruby 2.3 has a new feature that basically does what Rails' #strip_heredoc
does, but I haven't used it and I don't know how it handles multi-line interpolation. Here is the Ruby code for my custom solution based on your use case (using Ruby 2.0):
https://gist.github.com/shock/1d269a91f938bf1a1c3cba3856bedf19
Breaking up long strings on multiple lines in Ruby without stripping newlines
Three years later, there is now a solution in Ruby 2.3: The squiggly heredoc.
class Subscription
def warning_message
<<~HEREDOC
Subscription expiring soon!
Your free trial will expire in #{days_until_expiration} days.
Please update your billing information.
HEREDOC
end
end
Blog post link: https://infinum.co/the-capsized-eight/articles/multiline-strings-ruby-2-3-0-the-squiggly-heredocThe indentation of the least-indented line will be
removed from each line of the content.
How to print a string in erb file including line breaks
Since you tagged this question with ruby-on-rails
I guess you want to output to a webpage. I would recommend this:
<%= simple_format(str) %>
Form the docs:simple_format("Here is some basic text...\n...with a line break.")
# => "<p>Here is some basic text...\n<br />...with a line break.</p>"
Building multi-line strings, programmatically, in Ruby
This would be one way:
code = []
code << "next line of code #{something}"
code << "another line #{some_included_expression}"
code.join("\n")
Rails 3: Why does an indent appear when repopulating text_areas with line breaks?
Ok, the problem seemed to be the mix between html.haml
and html.erb
views in the application. So either the .erb
views are not properly rendered, or they don't play nice with the other .haml
views. In mi case, for example, the application layout view is in haml, but the form was in erb.
Whatever the cause, the bottom line is that the text_area_tags don't render correctly in erb, but do in haml. So my workaround, although I know it is very hacky and not pretty, was to make a small partial in haml called _text_area.html.haml
which renders just the textarea for a form:
_text_area.html.haml:
-if defined? options
= f.text_area field, options
-else
= f.text_area field
So every time I want to have a text_area tag in a form, I have to call a render like so:<%= form_for @instance do |f| %>
...
<%= render :partial => 'common/text_area', :locals => {:f => f, :field => :some_field_from_instance, :options => {:cols => 40, :rows => 10}} %>
<%= render :partial => 'common/text_area', :locals => {:f => f, :field => :some_other_field} %>
...
<% end %>
This renders perfectly. That's why I think the problem lies with haml and its interpretation of indentation. If anyone has a better solution, please do let me know. Looping over a string adds white space between characters in Ruby
Actually I then searched a more Ruby on Rails like solution, than above, so this then works for me to show any #word as a link, and it is much more simple.
<div class='tweet-text'>
<%= highlight(feed.text, /#\w+/, highlighter: '<a href="search?q=\1">\1</a>') %>
</div>
Related Topics
How to (Massively) Reduce The Number of SQL Queries in Rails App
Thor Executable - Ignore Task Name
What Is The Ruby Equivalent to This Curl Request
How to Fix a Deadlock in Join() in Ruby
How to Troubleshoot Memory Bloat at Boot for Rails App
How to Use Variable Arguments with Ruby's Optionparser
How Do Erlang Actors Differ from Oop Objects
Rails on Netbeans: Uncaught Exception: No Such File to Load - Script/Server or Script/Console
Rvm Finding System Gems' Executables
Ruby: Parse Excel 95-2003 Files
How to Reference a Local Gem from a Ruby Script
How to Make Two Thor Tasks Share Options
Ruby Gem Development - How to Use Activerecord
Difference Between @@ and @ in Ruby
How Can Multiple Trailing Slashes Can Be Removed from a Url in Ruby
Regex to Check Alphanumeric String in Ruby