Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby backslash to continue string on a new line?

Tags:

ruby

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?

like image 313
Andrew Avatar asked Jan 06 '15 05:01

Andrew


People also ask

How do you continue a line in Ruby?

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. Caution: + continues the statement but not the string. puts "foo"+"bar".

What does \n do in Ruby?

In double quoted strings, you can write escape sequences and Ruby will output their translated meaning. A \n becomes a newline. In single quoted strings however, escape sequences are escaped and return their literal definition. A \n remains a \n .

How do you create a multiline string in Ruby?

The easiest way to create a multiline string is to just use multiple lines between quotation marks: address = "Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal."

How do you make a new line in Ruby?

"\n" is newline, '\n\ is literally backslash and n.


3 Answers

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

like image 190
joelparkerhenderson Avatar answered Oct 18 '22 05:10

joelparkerhenderson


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.

like image 25
matt Avatar answered Oct 18 '22 04:10

matt


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.

like image 37
Amadan Avatar answered Oct 18 '22 04:10

Amadan