Skip to content

Commit d7d1109

Browse files
authored
Describe base code layout rules (ruby#15696)
* Describe base code layout rules * Enhance optional keyword explanation * Change the logical operators description
1 parent d517e04 commit d7d1109

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed

doc/syntax.rdoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
The Ruby syntax is large and is split up into the following sections:
44

5+
{Code Layout}[rdoc-ref:syntax/layout.rdoc] ::
6+
Breaking code in lines
7+
58
Literals[rdoc-ref:syntax/literals.rdoc] ::
69
Numbers, Strings, Arrays, Hashes, etc.
710

doc/syntax/layout.rdoc

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
= Code Layout
2+
3+
Expressions in Ruby are separated by line breaks:
4+
5+
x = 1
6+
y = 2
7+
z = x + y
8+
9+
Line breaks also used as logical separators of the headers of some of control structures from their bodies:
10+
11+
if z > 3 # line break ends the condition and starts the body
12+
puts "more"
13+
end
14+
15+
while x < 3 # line break ends the condition and starts the body
16+
x += 1
17+
end
18+
19+
<tt>;</tt> can be used as an expressions separator instead of a line break:
20+
21+
x = 1; y = 2; z = x + y
22+
if z > 3; puts "more"; end
23+
24+
Traditionally, expressions separated by <tt>;</tt> is used only in short scripts and experiments.
25+
26+
In some control structures, there is an optional keyword that can be used instead of a line break to separate their elements:
27+
28+
# if, elsif, until and case ... when: 'then' is an optional separator:
29+
30+
if z > 3 then puts "more" end
31+
32+
case x
33+
when Numeric then "number"
34+
when String then "string"
35+
else "object"
36+
end
37+
38+
# while and until: 'do' is an optional separator
39+
while x < 3 do x +=1 end
40+
41+
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+.
42+
43+
== Breaking expressions in lines
44+
45+
One expression might be split into several lines when each line can be unambiguously identified as "incomplete" without the next one.
46+
47+
These works:
48+
49+
x = # incomplete without something after =
50+
1 + # incomplete without something after +
51+
2
52+
53+
File.read "test.txt", # incomplete without something after ,
54+
enconding: "utf-8"
55+
56+
These would not:
57+
58+
# unintended interpretation:
59+
x = 1 # already complete expression
60+
+ 2 # interpreted as a separate +2
61+
62+
# syntax error:
63+
File.read "test.txt" # already complete expression
64+
, encoding: "utf-8" # attempt to parse as a new expression, SyntaxError
65+
66+
The exceptions to the rule are lines starting with <tt>.</tt> ("leading dot" style of method calls) or logical operators <tt>&&</tt>/<tt>||</tt> and <tt>and</tt>/<tt>or</tt>:
67+
68+
# OK, interpreted as a chain of calls
69+
File.read('test.txt')
70+
.strip("\n")
71+
.split("\t")
72+
.sort
73+
74+
# OK, interpreted as a chain of logical operators:
75+
File.empty?('test.txt')
76+
|| File.size('test.txt') < 10
77+
|| File.read('test.txt').strip.empty?
78+
79+
If the expressions is broken into multiple lines in any of the ways described above, comments between separate lines are allowed:
80+
81+
sum = base_salary +
82+
# see "yearly bonuses section"
83+
yearly_bonus(year) +
84+
# per-employee coefficient is described
85+
# in another module
86+
personal_coeff(employee)
87+
88+
# We want to short-circuit on empty files
89+
File.empty?('test.txt')
90+
# Or almost empty ones
91+
|| File.size('test.txt') < 10
92+
# Otherwise we check if it is full of spaces
93+
|| File.read('test.txt').strip.empty?
94+
95+
Finally, the code can explicitly tell Ruby that the expression is continued on the next line with <tt>\\</tt>:
96+
97+
# Unusual, but works
98+
File.read "test.txt" \
99+
, encoding: "utf-8"
100+
101+
# More regular usage (joins the strings on parsing instead
102+
# of concatenating them in runtime, as + would do):
103+
TEXT = "One pretty long line" \
104+
"one more long line" \
105+
"one other line of the text"
106+
107+
The <tt>\\</tt> works as a parse time line break escape, so with it, comments can not be inserted between the lines:
108+
109+
TEXT = "line 1" \
110+
# here would be line 2:
111+
"line 2"
112+
113+
# This is interpreted as if there was no line break where \ is,
114+
# i.e. the same as
115+
TEXT = "line 1" # here would be line 2:
116+
"line 2"
117+
118+
puts TEXT #=> "line 1"

0 commit comments

Comments
 (0)