<

Ruby Style

Common

  • Align function parameters either all on the same line or one per line
# bad
def self.create_translation(phrase_id, phrase_key, target_locale,
                            value, user_id, do_xss_check, allow_verification)
  ...
end

# good
def self.create_translation(phrase_id,
                            phrase_key,
                            target_locale,
                            value,
                            user_id,
                            do_xss_check,
                            allow_verification)
  ...
end

# good
def self.create_translation(
  phrase_id,
  phrase_key,
  target_locale,
  value,
  user_id,
  do_xss_check,
  allow_verification
)
  ...
end
  • Do not use default arguments. Use an options hash instead
# bad
def obliterate(things, gently = true, except = [], at = Time.now)
  ...
end

# good
def obliterate(things, options = {})
  default_options = {
    :gently => true, # obliterate with soft-delete
    :except => [], # skip obliterating these things
    :at => Time.now, # don't obliterate them until later
  }
  options.reverse_merge!(default_options)

  ...
end
  • Avoid class « self except when necessary, e.g. single accessors and aliased attributes
class TestClass
  # bad
  class << self
    def first_method
      ...
    end

    def second_method_etc
      ...
    end
  end

  # good
  class << self
    attr_accessor :per_page
    alias_method :nwo, :find_by_name_with_owner
  end

  def self.first_method
    ...
  end

  def self.second_method_etc
    ...
  end
end
  • Indent the public, protected, and private methods as much the method definitions they apply to. Leave one blank line above and below them
class SomeClass
  def public_method
    # ...
  end

  private

  def private_method
    # ...
  end
end
  • Don’t use exceptions for flow of control
# bad
begin
  n / d
rescue ZeroDivisionError
  puts "Cannot divide by 0!"
end

# good
if d.zero?
  puts "Cannot divide by 0!"
else
  n / d
end
  • Avoid rescuing the Exception class
# bad
begin
  # an exception occurs here
rescue Exception
  # exception handling
end

# good
begin
  # an exception occurs here
rescue StandardError
  # exception handling
end

# acceptable
begin
  # an exception occurs here
rescue
  # exception handling
end
  • Don’t specify RuntimeError explicitly in the two argument version of raise. Prefer error sub-classes for clarity and explicit error creation
# bad
raise RuntimeError, 'message'

# better - RuntimeError is implicit here
raise 'message'

# best
class MyExplicitError < RuntimeError; end
raise MyExplicitError
  • Collections

  • Prefer map over collect.

  • Prefer detect over find. The use of find is ambiguous with regard to ActiveRecord’s find method - detect makes clear that you’re working with a Ruby collection, not an AR object.

  • Prefer reduce over inject.

  • Prefer size over either length or count for performance reasons

  • Be careful with ^ and $ as they match start/end of line, not string endings. If you want to match the whole string use: \A and \z

string = "some injection\nusername"
string[/^username$/]   # matches
string[/\Ausername\z/] # don't match
  • Use x modifier for complex regexps. This makes them more readable and you can add some useful comments. Just be careful as spaces are ignored
regexp = %r{
  start         # some text
  \s            # white space char
  (group)       # first group
  (?:alt1|alt2) # some alternation
  end
}x
  • Prefer parentheses over curly braces, brackets, or pipes when using %-literal delimiters for consistency, and because the behavior of %-literals is closer to method calls than the alternatives
# bad
%w[date locale]
%w{date locale}
%w|date locale|

# good
%w(date locale)

Percent Literals

  • Prefer parentheses over curly braces, brackets, or pipes when using %-literal delimiters for consistency, and because the behavior of %-literals is closer to method calls than the alternatives
# bad
%w[date locale]
%w{date locale}
%w|date locale|

# good
%w(date locale)
  • Use %() for single-line strings which require both interpolation and embedded double-quotes. For multi-line strings, prefer heredocs
# 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>)```

### Use %r only for regular expressions matching more than one '/' character

```ruby
# bad
%r(\s+)

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

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

### Avoid the use of %x unless you're going to invoke a command with backquotes in it (which is rather unlikely)

```ruby
# bad
date = %x(date)

# good
date = `date`
echo = %x(echo `date`)

Rails

  • When immediately returning after calling render or redirect_to, put return on the next line, not the same line
# bad
render :text => 'Howdy' and return

# good
render :text => 'Howdy'
return

# still bad
render :text => 'Howdy' and return if foo.present?

# good
if foo.present?
  render :text => 'Howdy'
  return
end