Ruby Style Guide

Ruby Style Guide

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

sum = 1 + 2
a, b = 1, 2
1 > 2 ? true : false; puts "hi"
[1, 2, 3].each { |e| puts e }
some(arg).other
[1, 2, 3].length
case
when song.name == 'Tik Tok'
  puts "Not again!"
when song.duration > 120
  puts "That's really long"
when Time.now.hour > 21
  puts "It's time to start coding"
else
  song.play
end

epoch = case year
        when 1607..1777 then "Colonial Period"
        when 1778..1812 then "Early Republic"
def some_method
  do_something
  do_something_else

  result
end

def do_something
  result
end

Syntax

def some_method
  # payload
end

def method_with_arguments(arg1, arg2)
  # payload
end
arr = [1, 2, 3]

# bad
for elem in arr do
  puts elem
end

# good
array.each { |elem| puts elem }
# bad
if some_condition then
  # payload
end

# good
if some_condition
  # payload
end
# bad
result = if some_condition then something else something_else end

# good
result = some_condition ? something : something_else
# bad
some_condition ? (nested_condition ? nested_something : nested_something_else) : something_else

# good
if some_condition
  nested_condition ? nested_something : nested_something_else
else
  something_else
end
# boolean expression
if some_condition && some_other_condition
  do_something
end

# control flow
document.saved? or document.save!
# bad
if some_condition
  do_something
end

# good
do_something if some_condition

# another good option
some_condition and do_something
# bad
do_something if !some_condition

# good
do_something unless some_condition

# another good option
some_condition or do_something
x = Math.sin(y)
array.delete e
# bad
def some_method(some_arr)
  return some_arr.size
end

# good
def some_method(some_arr)
  some_arr.size
end
# bad
result = 1 - \
         2

# good (but still ugly as hell)
result = 1 \
         - 2
if v = array.grep(/foo/) ...
# set name to Bozhidar, only if it's nil or false
name ||= "Bozhidar"
def bar
  # FIXME: This has crashed occasionally since v3.2.1. It may
  #   be related to the BarBazUtil upgrade.
  baz(:quux)
end
def bar
  sleep 100 # OPTIMIZE
end

Classes

Exceptions

Strings

# bad
email_with_name = user.name + ' <' + user.email + '>'

# good
email_with_name = "#{user.name} <#{user.email}>"
# good and also fast
html = ''
html << '<h1>Page title</h1>'

paragraphs.each do |paragraph|
  html << "<p>#{paragraph}</p>"
end

Percent Literals

STATES = %w(draft open closed)
# bad (no interpolation needed)
%(<div class="text">Some text</div>)
# should be '<div class="text">Some text</div>'

# bad (no double-quotes)
%(This is #{quality} style)
# should be "This is #{quality} style"

# bad (multiple lines)
%(<div>\n<span class="big">#{exclamation}</span>\n</div>)
# should be a heredoc.

# good (requires interpolation, has quotes, single line)
%(<tr><td class="name">#{name}</td>)
# bad
%r(\s+)

# still bad
%r(^/(.*)$)
# should be /^\/(.*)$/

# good
%r(^/blog/2011/(.*)$)

Misc

class TestClass
  # bad
  def TestClass.some_method
    # body omitted
  end

  # good
  def self.some_other_method
    # body omitted
  end

  # Also possible and convenient when you
  # have to define many singleton methods.
  class << self
    def first_method
      # body omitted
    end

    def second_method_etc
      # body omitted
    end
  end
end
#bad
$foo_bar = 1

#good
class Foo
  class << self
    attr_accessor :bar
  end
end

Foo.bar = 1
  [1, 2, 3].inject(:+)

Design