• Never use do for multi-line while or
      until.[link]

      1. # bad
      2. while x > 5 do
      3. ...
      4. end
      5. until x > 5 do
      6. ...
      7. end
      8. # good
      9. while x > 5
      10. ...
      11. end
      12. until x > 5
      13. ...
      14. end
    • The and, or, and not keywords are banned. It’s
      just not worth it. Always use &&, ||, and ! instead.
      [link]

    • Modifier if/unless usage is okay when
      the body is simple, the condition is simple, and the whole thing fits on
      one line. Otherwise, avoid modifier if/unless.
      [link]

      1. # bad - this doesn't fit on one line
      2. add_trebuchet_experiments_on_page(request_opts[:trebuchet_experiments_on_page]) if request_opts[:trebuchet_experiments_on_page] && !request_opts[:trebuchet_experiments_on_page].empty?
      3. # okay
      4. if request_opts[:trebuchet_experiments_on_page] &&
      5. !request_opts[:trebuchet_experiments_on_page].empty?
      6. add_trebuchet_experiments_on_page(request_opts[:trebuchet_experiments_on_page])
      7. end
      8. # bad - this is complex and deserves multiple lines and a comment
      9. parts[i] = part.to_i(INTEGER_BASE) if !part.nil? && [0, 2, 3].include?(i)
      10. # okay
      11. return if reconciled?
    • Never use unless with else. Rewrite
      these with the positive case first.[link]

      1. # bad
      2. unless success?
      3. puts 'failure'
      4. else
      5. puts 'success'
      6. # good
      7. puts 'success'
      8. else
      9. puts 'failure'
      10. end
    • Avoid unless with comparison operators if you can use if with an opposing comparison operator.[link]

      1. # bad
      2. unless x == 10
      3. ...
      4. end
      5. # good
      6. if x != 10
      7. ...
      8. end
      9. # bad
      10. unless x < 10
      11. ...
      12. end
      13. # good
      14. if x >= 10
      15. ...
      16. end
      17. # ok
      18. unless x === 10
      19. ...
      20. end
    • Don’t use parentheses around the
      condition of an if/unless/while.
      [link]

      1. # bad
      2. if (x > 10)
      3. ...
      4. end
      5. # good
      6. if x > 10
      7. ...
      8. end
    • Avoid the ternary operator (?:) except
      in cases where all expressions are extremely trivial. However, do use the
      ternary operator(?:) over if/then/else/end constructs for single line
      conditionals.[link]

      1. # bad
      2. result = if some_condition then something else something_else end
      3. # good
    • Use one expression per branch in a ternary
      operator. This also means that ternary operators must not be nested. Prefer
      if/else constructs in these cases.[link]


    • Avoid the use of nested conditionals for flow of control.
      ([More on this][avoid-else-return-early].) [link]

      Prefer a guard clause when you can assert invalid data. A guard clause
      is a conditional statement at the top of a function that returns as soon
      as it can.

      The general principles boil down to:

      • Return immediately once you know your function cannot do anything more.
      • Reduce nesting and indentation in the code by returning early. This makes
        the code easier to read and requires less mental bookkeeping on the part
        of the reader to keep track of else branches.
      • The core or most important flows should be the least indented.
      1. # bad
      2. def compute
      3. server = find_server
      4. if server
      5. client = server.client
      6. if client
      7. request = client.make_request
      8. if request
      9. process_request(request)
      10. end
      11. end
      12. end
      13. end
      14. # good
      15. def compute
      16. server = find_server
      17. return unless server
      18. client = server.client
      19. return unless client
      20. request = client.make_request
      21. return unless request
      22. process_request(request)
      23. end
      1. # bad
      2. [0, 1, 2, 3].each do |item|
      3. if item > 1
      4. puts item
      5. end
      6. end
      7. # good
      8. [0, 1, 2, 3].each do |item|
      9. next unless item > 1
      10. end

      See also the section “Guard Clause”, p68-70 in Beck, Kent.
      Implementation Patterns. Upper Saddle River: Addison-Wesley, 2008, which
      has inspired some of the content above.