Ruby Style Guide
Styleguide for writing Ruby applications
These styles are adapted from the excellent work Bozhidar Batsov posted on his Ruby Style Guide project.
Nearly everybody is convinced that every style but their own is ugly and unreadable. Leave out the "but their own" and they're probably right...
Jeffy Coffin
Formatting
- Use UTF-8 as the source file encoding
- Use two-space indent (NO TABS)
-
Use Unix style line endings
Use
$git config --global core.autoclrf true
to ensure Window’s style doesn’t creep in - Use spaces around operators, and curly braces (‘
{
’, ‘}
’) after commas and semicolons
- No spaces after ‘
(
’, or between braces (‘[
’, ‘]
’).
- Indent
when
as deep ascase
.
- Use an empty line before the return value of a method (unless it only
has one line), and an empty line betwee
def
declarations.
- Use RDoc and its conventions for documentation (SDoc may be used to generate more searchable documentation).
- Use empty lines to break up a method in to logical paragraphs.
- Keep lines to fewer than 80 characters.
Syntax
- Use
def
with parentheses when there are arguments. Omit parentheses when the method does not accept any arguments
- Never use
for
, unleass you know exactly why. Iterators should be used instead
- Never use
then
for multi-lineif/unless
- Favor ther ternary operator over
if/then/else/end
constructs. It’s more common and concise.
- Use one expression per branch in a ternary operator. This also means that ternary operators must not be nested. Prefer
if/els
e constructs in these cases.
- Use
&&
and||
for boolean expressions. Useand
andor
for flow control.
- Avoid multi-line ternary operations, use
if/unless
instead - Favor modifier
if/unless
usage when you have a single-line body.
- Favor
unless
overif
for negative conditions (or control flowor
)
- Suppress superfluous parentheses when calling methods, but keep them when calling “functions”, i.e. when you use the return value in the same line.
-
Prefer {…} over do…end for single-line blocks. Avoid using {…} for multi-line blocks. Always use do…end for “control flow” and “method definitions” (e.g. in Rakefiles and certain DSLs.) Avoid do…end when chaining.
-
Avoid
return
where not required.
- Avoid line continuation (\) where not required. In practice, avoid using line continuations at all.
- Using the return value of = is ok.
-
Use = freely.
- Avoid using Perl-style special variables (like $0-9, $`, …).
-
The annotation keyword is followed by a colon and a space, then a note describing the problem.
- If multiple lines are required to describe the problem, subsequent
lines should be indented two spaces after the
#
.
- In cases where the problem is so obvious that any documentation would be redundant, annotations may be left at the end of the offending line with no note. This usage should be the exception and not the rule.
-
Use
TODO
to note missing features or functionality that should be added at a later date. -
Use
FIXME
to note broken code that needs to be fixed. -
Use
OPTIMIZE
to note slow or inefficient code that may cause performance problems. -
Use
HACK
to note code smells where questionable coding practices were used and should be refactored away. -
Use
REVIEW
to note anything that should be looked at to confirm it is working as intended. For example:REVIEW: Are we sure this is how the client does X currently?
-
Use other custom annotation keywords if it feels appropriate, but be sure to document them in your project’s
README
or similar.
Classes
- Always supply a proper
to_s
method. - Use the
attr
family of functions to define trivial accessors or mutators. - Consider adding factory methods to provide additional sensible ways to create instances of a particular class.
- Prefer duck-typing over inheritance.
- Avoid the usage of class (@@) variables due to their “nasty” behavior in inheritance.
- Assign proper visibility levels to methods (
private
,protected
) in accordance with their intended usage. Don’t go off leaving everythingpublic
(which is the default). After all we’re coding in Ruby now, not in Python.
Exceptions
- Don’t suppress exceptions.
- Don’t use exceptions for flow of control.
- Avoid rescuing the
Exception
class.
Strings
- Prefer string interpolation instead of string concatenation:
- Prefer single-quoted strings when you don’t need string interpolation or
special symbols such as
"\t"
,"\n"
, etc. - Avoid using
String#+
when you need to construct large data chunks. Instead, useString#<<
. Concatenation mutates the string instance in-place and is always faster thanString#+
, which creates a bunch of new string objects.
Percent Literals
- Use
%w
freely.
- Use
%()
for single-line strings which require both interpolation and embedded double-quotes. For multi-line strings, prefer heredocs.
- Use
%r
only for regular expressions matching more than one ‘/’ character.
-
Avoid
%q
,%Q
,%x
,%s
, and%W
. -
Prefer
()
as delimiters for all%
literals.
Misc
- Write
ruby -w
safe code. - Avoid hashes as optional parameters. Does the method do too much?
- Avoid methods longer than 10 LOC (lines of code). Ideally, most methods will be shorter than 5 LOC. Empty lines do not contribute to the relevant LOC.
- Avoid parameter lists longer than three or four parameters.
- Use
def self.method
to define singleton methods. This makes the methods more resistant to refactoring changes.
- If you really have to, add “global” methods to Kernel and make them private.
- Use class instance variables instead of global variables.
- Avoid
alias
whenalias_method
will do. - Use
OptionParser
for parsing complex command line options andruby -s
for trivial command line options. - Write for Ruby 1.9. Don’t use legacy Ruby 1.8 constructs.
- Use the new JavaScript literal hash syntax.
- Use the new lambda syntax.
- Methods like
inject
now accept method names as arguments.
- Avoid needless metaprogramming.
Design
- Use common sense.
- Code in a functional way, avoiding mutation when that makes sense.
- Do not mutate arguments unless that is the purpose of the method.
- Do not mess around in core classes when writing libraries. (Do not monkey patch them.)
- Do not program defensively.
- Keep the code simple (although this is subjective). Each method should have a single, well-defined responsibility.
- Avoid more than three levels of block nesting.
- Don’t overdesign. Overly complex solutions tend to be brittle and hard to maintain.
- Don’t underdesign. A solution to a problem should be as simple as possible, but no simpler than that. Poor initial design can lead to a lot of problems in the future.
- Be consistent. In an ideal world, be consistent with these guidelines.