Source Code Layout
Use
UTF-8
as the source file encoding. [link]Use two spaces per indentation level (a.k.a. soft tabs). No hard tabs. [link]
# bad: four spaces def some_method do_something end # good def some_method do_something end
Use Unix-style line endings. (BSD/Solaris/Linux/OS X users are covered by default, but Windows users have to be extra careful.) [link]
If you're using Git you might want to add the following configuration setting to protect your project from Windows line endings creeping in:
$ git config --global core.autocrlf true
Don't use
;
to separate statements and expressions. As a corollary, use one expression per line. [link]# bad puts "foobar"; # superfluous semicolon puts "foo"; puts "bar" # two expressions on the same line # good puts "foobar" puts "foo" puts "bar" puts "foo", "bar" # this applies to puts in particular
Prefer a single-line format for class definitions with no body. [link]
# bad class FooError < StandardError end # passable class FooError < StandardError; end # good FooError = Class.new(StandardError)
Use spaces around operators, after commas, colons and semicolons, and around
{
and before}
when used in blocks. Whitespace might be (mostly) irrelevant to the Ruby interpreter, but its proper use is the key to writing easily readable code. [link]sum = 1 + 2 a, b = 1, 2 [1, 2, 3].each { |e| puts e } class FooError < StandardError; end
The only exception, regarding operators, is the exponent operator:
# bad e = M * c ** 2 # good e = M * c**2
No spaces after
(
,[
, or{
when used for hash literals or interpolation. No spaces before]
,)
, or}
when used for hash literals or interpolation. [link]# bad some( arg ).other [ 1, 2, 3 ].size # good some(arg).other [1, 2, 3].size
No space after
!
. [link]# bad ! something # good !something
No space inside range literals. [link]
# bad 1 .. 3 "a" ... "z" # good 1..3 "a"..."z"
Indent
when
as deep ascase
. This is the style established in both "The Ruby Programming Language" and "Programming Ruby". [link]# bad case when song.name == "Misty" puts "Not again!" when song.duration > 120 puts "Too long!" when Time.now.hour > 21 puts "It's too late" else song.play end # good case when song.name == "Misty" puts "Not again!" when song.duration > 120 puts "Too long!" when Time.now.hour > 21 puts "It's too late" else song.play end
When assigning the result of a conditional expression to a variable, move the conditional to a new line and indent one level. [link]
# bad: pretty convoluted kind = case year when 1850..1889 then "Blues" when 1890..1909 then "Ragtime" when 1910..1929 then "New Orleans Jazz" when 1930..1939 then "Swing" when 1940..1950 then "Bebop" else "Jazz" end result = if some_cond calc_something else calc_something_else end # bad: random indentation and all lines change with the variable name kind = case year when 1850..1889 then "Blues" when 1890..1909 then "Ragtime" when 1910..1929 then "New Orleans Jazz" when 1930..1939 then "Swing" when 1940..1950 then "Bebop" else "Jazz" end result = if some_cond calc_something else calc_something_else end # good (and a bit more width efficient) kind = case year when 1850..1889 then "Blues" when 1890..1909 then "Ragtime" when 1910..1929 then "New Orleans Jazz" when 1930..1939 then "Swing" when 1940..1950 then "Bebop" else "Jazz" end result = if some_cond calc_something else calc_something_else end
Use empty lines between method definitions and also to break up methods into logical paragraphs internally. [link]
def some_method data = initialize(options) data.manipulate! data.result end def some_method result end
Avoid a comma after the last parameter in a method call when the parameters are on the same line. [link]
# bad some_method(size, count, color, ) # good some_method(size, count, color)
Use spaces around the
=
operator when assigning default values to method parameters: [link]# bad def some_method(arg1=:default, arg2=nil, arg3=[]) # do something... end # good def some_method(arg1 = :default, arg2 = nil, arg3 = []) # do something... end
While several Ruby books suggest the first style, the second is much more prominent in practice (and arguably a bit more readable).
Avoid using line continuation (
\
). [link]# bad result = 1 - \ 2 result = 1 \ - 2 # passable long_string = "First part of the long string" \ " and second part of the long string" # good long_string = "First part of the long string" + " and second part of the long string"
When continuing a chained method invocation on another line, include the
.
on the first line to indicate that the expression continues. [link]# bad: makes the code harder to play with in a REPL one.two.three .four # passable: irb friendly one.two.three. four # good one. two. three. four
Align the parameters of a method call if they span more than one line. When aligning parameters, single indent parameter lines. [link]
# bad: line is too long def send_mail(source) Mailer.deliver(to: "[email protected]", from: "[email protected]", subject: "Important message", body: source.text) end # bad: double indent def send_mail(source) Mailer.deliver( to: "[email protected]", from: "[email protected]", subject: "Important message", body: source.text) end # bad: random indention that can easily cause all lines to change def send_mail(source) Mailer.deliver(to: "[email protected]", from: "[email protected]", subject: "Important message", body: source.text) end # good: normal indent def send_mail(source) Mailer.deliver( to: "[email protected]", from: "[email protected]", subject: "Important message", body: source.text ) end
Align the elements of array literals spanning multiple lines. [link]
# bad: single indent menu_item = ["Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam"] # passable menu_item = ["Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam"] # good menu_item = [ "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Spam", "Baked beans", "Spam", "Spam", "Spam", "Spam", "Spam" ]
Add underscores to large numeric literals to improve their readability. [link]
# bad: how many 0s are there? num = 1000000 # good: much easier to parse for the human brain num = 1_000_000
Use RDoc and its conventions for API documentation. Don't put an empty line between the comment block and the
def
. [link]Limit lines to 80 characters. [link]
Avoid trailing whitespace. [link]
End each file with a newline. [link]
Don't use block comments. They cannot be preceded by whitespace and are not as easy to spot as regular comments. [link]
# bad =begin comment line another comment line =end # good # comment line # another comment line