Reputation: 5220
We recently decided at my job to a ruby style guide. One of the edicts is that no line should be wider than 80 characters. Since this is a Rails project, we often have strings that are a little bit longer - i.e. "User X wanted to send you a message about Thing Y" that doesn't always fit within the 80 character style limit.
I understand there are three ways to have a long string span multiple lines:
However, all of these cases end up taking more computation cycles, which seems silly. String concatenation obviously, but for HEREDOC
and %Q
I have to strip out the newlines, via something like .gsub(/\n$/, '')
.
Is there a pure syntax way to do this, that is equivalent to just having the whole string on one line? The goal being, obviously, to not spend any extra cycles just because I want my code to be slightly more readable. (Yes, I realize that you have to make that tradeoff a lot...but for string length, this just seems silly.)
Update: Backslashes aren't exactly what I want because you lose indentation, which really affects style/readability.
Example:
if foo
string = "this is a \
string that spans lines"
end
I find the above a bit hard to read.
EDIT: I added an answer below; three years later we now have the squiggly heredoc.
Upvotes: 302
Views: 178347
Reputation: 1937
If you want to use backslash, and want to indent your strings, just wrap them in quotes:
str = "This is a multi" \
"line string!"
puts str
This is a multiline string!
Upvotes: 1
Reputation: 102
Squish in Rails is doing what you need.
https://apidock.com/rails/String/squish
End it looks like this:
%{ Multi-line
string }.squish
And because you need it in Ruby, just look at Rails code:
%{ Multi-line
string }
.gsub!(/[[:space:]]+/, " ")
.strip!
Upvotes: 3
Reputation: 456
This is by now a very old question but as the issue still seems to come up here's an updated answer. Since the original poster indicated this was for a Rails project you can look to Rails' String inflections for help.
my_long_string = <<-STRING
hello
there
multiline
multiindented string
STRING
=> " hello\n there\n multiline\n multiindented string\n"
Enter the squish
method.
my_long_string = <<-STRING.squish
so
long
multiline
multiindented string
STRING
=> "so long multiline multiindented string"
As per the docs -
squish()
Returns the string, first removing all whitespace on both ends of the string, and then changing remaining consecutive whitespace groups into one space each.
Upvotes: 28
Reputation: 83
You can concatenate multiple strings split over several lines:
if foo
string = "this is a" +
"string that spans lines"
end
Upvotes: 0
Reputation: 11872
I had this problem when I try to write a very long url, the following works.
image_url = %w(
http://minio.127.0.0.1.xip.io:9000/
bucket29/docs/b7cfab0e-0119-452c-b262-1b78e3fccf38/
28ed3774-b234-4de2-9a11-7d657707f79c?
X-Amz-Algorithm=AWS4-HMAC-SHA256&
X-Amz-Credential=ABABABABABABABABA
%2Fus-east-1%2Fs3%2Faws4_request&
X-Amz-Date=20170702T000940Z&
X-Amz-Expires=3600&X-Amz-SignedHeaders=host&
X-Amz-Signature=ABABABABABABABABABABAB
ABABABABABABABABABABABABABABABABABABA
).join
Note, there must not be any newlines, white spaces when the url string is formed. If you want newlines, then use HEREDOC.
Here you have indentation for readability, ease of modification, without the fiddly quotes and backslashes on every line. The cost of joining the strings should be negligible.
Upvotes: 23
Reputation: 2047
I modified Zack's answer since I wanted spaces and interpolation but not newlines and used:
%W[
It's a nice day "#{name}"
for a walk!
].join(' ')
where name = 'fred'
this produces It's a nice day "fred" for a walk!
Upvotes: 19
Reputation: 5220
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-heredoc
The indentation of the least-indented line will be removed from each line of the content.
Upvotes: 60
Reputation: 5232
Maybe this is what you're looking for?
string = "line #1"\
"line #2"\
"line #3"
p string # => "line #1line #2line #3"
Upvotes: 554
Reputation: 18193
You can use \
to indicate that any line of Ruby continues on the next line. This works with strings too:
string = "this is a \
string that spans lines"
puts string.inspect
will output "this is a string that spans lines"
Upvotes: 72