Code Layout ↑

Expressions in Ruby are separated by line breaks:

x = 1
y = 2
z = x + y

Line breaks are also used as logical separators of the headers of some control structures from their bodies:

if z > 3       # line break ends the condition and starts the body
  puts "more"
end

while x < 3    # line break ends the condition and starts the body
  x += 1
end

; can be used as an expressions separator instead of a line break:

x = 1; y = 2; z = x + y
if z > 3; puts "more"; end

Traditionally, expressions separated by ; are used only in short scripts and experiments.

In some control structures, there is an optional keyword that can be used instead of a line break to separate their elements:

# if, elsif, until and case ... when: 'then' is an optional separator:

if z > 3 then puts "more" end

case x
when Numeric then "number"
when String then "string"
else "object"
end

# while and until: 'do' is an optional separator
while x < 3 do x +=1 end

Also, line breaks can be skipped in some places where it doesn’t create any ambiguity. Note in the example above: no line break needed before end, just as no line break needed after else.

Breaking expressions in lines ↑

One expression might be split into several lines when each line can be unambiguously identified as “incomplete” without the next one.

These works:

x =         # incomplete without something after =
    1 +     # incomplete without something after +
    2

File.read "test.txt",         # incomplete without something after ,
          encoding: "utf-8"

These would not:

# unintended interpretation:
x = 1     # already complete expression
    + 2   # interpreted as a separate +2

# syntax error:
File.read "test.txt"           # already complete expression
          , encoding: "utf-8"  # attempt to parse as a new expression, SyntaxError

The exceptions to the rule are lines starting with . (“leading dot” style of method calls) or logical operators &&/|| and and/or:

# OK, interpreted as a chain of calls
File.read('test.txt')
    .strip("\n")
    .split("\t")
    .sort

# OK, interpreted as a chain of logical operators:
File.empty?('test.txt')
  || File.size('test.txt') < 10
  || File.read('test.txt').strip.empty?

If the expressions is broken into multiple lines in any of the ways described above, comments between separate lines are allowed:

sum = base_salary +
      # see "yearly bonuses section"
      yearly_bonus(year) +
      # per-employee coefficient is described
      # in another module
      personal_coeff(employee)

# We want to short-circuit on empty files
File.empty?('test.txt')
  # Or almost empty ones
  || File.size('test.txt') < 10
  # Otherwise we check if it is full of spaces
  || File.read('test.txt').strip.empty?

Finally, the code can explicitly tell Ruby that the expression is continued on the next line with \:

# Unusual, but works
File.read "test.txt" \
          , encoding: "utf-8"

# More regular usage (joins the strings on parsing instead
# of concatenating them in runtime, as + would do):
TEXT = "One pretty long line" \
       "one more long line" \
       "one other line of the text"

The \ works as a parse time line break escape, so with it, comments can not be inserted between the lines:

TEXT = "line 1" \
       # here would be line 2:
       "line 2"

# This is interpreted as if there was no line break where \ is,
# i.e. the same as
TEXT = "line 1" # here would be line 2:
       "line 2"

puts TEXT #=> "line 1"