Reputation: 238667
I'm reviewing a line of Ruby code in a pull request. I'm not sure if this is a bug or a feature that I haven't seen before:
puts "A string of Ruby that"\
"continues on the next line"
Is the backslash a valid character to concatenate these strings? Or is this a bug?
Upvotes: 39
Views: 25610
Reputation: 35443
That is valid code.
The backslash is a line continuation. Your code has two quoted runs of text; the runs appear like two strings, but are really just one string because Ruby concatenates whitespace-separated runs.
Example of three quoted runs of text that are really just one string:
"a" "b" "c"
=> "abc"
Example of three quoted runs of text that are really just one string, using \
line continuations:
"a" \
"b" \
"c"
=> "abc"
Example of three strings, using +
line continuations and also concatenations:
"a" +
"b" +
"c"
=> "abc"
Other line continuation details: "Ruby interprets semicolons and newline characters as the ending of a statement. However, if Ruby encounters operators, such as +, -, or backslash at the end of a line, they indicate the continuation of a statement." - Ruby Quick Guide
Edit: Good clarification from @cesoid in the comments... Backslash only indicates the continuation of a statement, whereas + and - continue the statement and perform their normal operation. In other words, the backslash gets "removed", but the + and - don't. It makes more sense to say that + and - are operators that work across multiple lines (as do other things in ruby). Backslashes are different. For example, putting backlslashes between two strings on one line causes a syntax error.
Upvotes: 40
Reputation: 534950
The backslash character does not concatenate any strings. It prevents the line-break from meaning that those two lines are different statements. Think of the backslash as the opposite of the semicolon. The semicolon lets two statements occupy one line; the backslash lets one statement occupy two lines.
What you are not realizing is that a string literal can be written as multiple successive literals. This is legal Ruby:
s = "A string of Ruby that" "continues on the same line"
puts s
Since that is legal, it is legal to put a line break between the two string literals - but then you need the backslash, the line-continuation character, to tell Ruby that these are in fact the same statement, spread over two lines.
s = "A string of Ruby that" \
"continues on the same line"
puts s
If you omit the backslash, it is still legal, but doesn't give the result you might be hoping for; the string literal on the second line is simply thrown away.
Upvotes: 35
Reputation: 198324
This is not a case of concatenated strings. It is one single string. "foo" "bar"
is a syntactic construct that allows you to break up a string in your code, but it is identical to "foobar"
. In contrast, "foo" + "bar"
is the true concatenation, invoking the concatenation method +
on object "foo"
.
You can verify this by dumping the YARV instructions. Compare:
RubyVM::InstructionSequence.compile('"foo" + "bar"').to_a
// .... [:putstring, "foo"], [:putstring, "bar"] ....
RubyVM::InstructionSequence.compile('"foo" "bar"').to_a
// .... [:putstring, "foobar"] ....
The backslash in front of the newline will cancel the newline, so it does not terminate the statement; without it, it would not be one string, but two strings in separate lines.
Upvotes: 8