Skip to content

Instantly share code, notes, and snippets.

@antonrogov
Created September 14, 2011 11:21

Revisions

  1. antonrogov revised this gist Sep 14, 2011. 1 changed file with 2 additions and 0 deletions.
    2 changes: 2 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -1,3 +1,5 @@
    # Ruby Coding Guidelines

    ## Formatting

    * Use UTF-8 as the source file encoding.
  2. antonrogov created this gist Sep 14, 2011.
    300 changes: 300 additions & 0 deletions gistfile1.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,300 @@
    ## Formatting

    * Use UTF-8 as the source file encoding.
    * Use 2 space indent, no tabs. (Your editor/IDE should have a setting to help you with that)
    * Use Unix-style line endings. (Linux/OSX users are covered by default, Windows users have to be extra careful)
    * if you're using Git you might want to do this `$ git config --global core.autocrlf true` to protect your project from Windows line endings creeping into your project
    * Use spaces around operators, after commas, colons and semicolons, before { and }.

    ```Ruby
    sum = 1 + 2
    a, b = 1, 2
    1 > 2 ? true : false; puts "Hi"
    [1, 2, 3].each {|e| puts e }
    ```

    * No spaces after (, [ or before ], ).

    ```Ruby
    some(arg).other
    [1, 2, 3].length
    ```

    * Indent **when** as deep as **case**. (as suggested in the Pickaxe)

    ```Ruby
    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
    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
    ```

    * Use an empty line before the return value of a method (unless it
    only has one line), and an empty line between defs.

    ```Ruby
    def some_method
    do_something
    do_something_else
    result
    end
    def some_method
    result
    end
    ```

    * Use RDoc and its conventions for API documentation. Don't put an
    empty line between the comment block and the **def**.
    * Use empty lines to break up a method into logical paragraphs.
    * Keep lines fewer than 80 characters.
    * Emacs users should really have a look at whitespace-mode
    * Avoid trailing whitespace.
    * Emacs users - whitespace-mode again comes to the rescue
    ## Syntax
    * Use **def** with parentheses when there are arguments. Omit the
    parentheses when the method doesn't accept any arguments.

    ```Ruby
    def some_method
    # body omitted
    end
    def some_method_with_arguments(arg1, arg2)
    # body omitted
    end
    ```

    * Never use **for**, unless you exactly know why. Most of the time iterators should be used instead.

    ```Ruby
    arr = [1, 2, 3]
    # bad
    for elem in arr do
    puts elem
    end
    # good
    arr.each {|elem| puts elem }
    ```

    * Never use **then** for multiline **if/unless**.

    ```Ruby
    # bad
    if x.odd? then
    puts "odd"
    end
    # good
    if x.odd?
    puts "odd"
    end
    ```

    * Use **when x; ...** for one-line cases.
    * Use &&/|| for boolean expressions, and/or for control flow. (Rule
    of thumb: If you have to use outer parentheses, you are using the
    wrong operators.)
    * Avoid multiline ?: (the ternary operator), use **if/unless** instead.
    * Favor modifier **if/unless** usage when you have a single-line body.

    ```Ruby
    # bad
    if some_condition
    do_something
    end
    # good
    do_something if some_condition
    # another good option
    some_condition && do_something
    ```

    * Favor **unless** over **if** for negative conditions:

    ```Ruby
    # bad
    do_something if !some_condition
    # good
    do_something unless some_condition
    # another good option
    some_condition || do_something
    ```

    * Suppress superfluous parentheses when calling methods, but keep them
    when calling "functions", i.e. when you use the return value in the
    same line.

    ```Ruby
    x = Math.sin(y)
    array.delete e
    ```

    * Prefer {...} over do...end. Multiline {...} is fine: having
    different statement endings (} for blocks, end for if/while/...)
    makes it easier to see what ends where. But 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.

    ```Ruby
    # bad
    def some_method(some_arr)
    return some_arr.size
    end
    # good
    def some_method(some_arr)
    some_arr.size
    end
    ```

    * Avoid line continuation (\\) where not required. In practice avoid using line continuations at all.

    ```Ruby
    # bad
    result = 1 + \
    2
    # good (but still ugly as hell)
    result = 1 \
    \+ 2
    ```

    * Using the return value of = is okay:

    ```Ruby
    if v = array.grep(/foo/) ...
    ```

    * Use ||= freely.

    ```Ruby
    # set name to Bozhidar, only if it's nil or false
    name ||= "Bozhidar"
    ```

    * Avoid using Perl-style global variables(like $0-9, $`, ...)

    ## Naming

    * Use snake_case for methods and variables.
    * Use CamelCase for classes and modules. (Keep acronyms like HTTP,
    RFC, XML uppercase.)
    * Use SCREAMING_SNAKE_CASE for other constants.
    * The length of an identifier determines its scope. Use one-letter variables for short block/method parameters, according to this scheme:

    a,b,c: any object
    d: directory names
    e: elements of an Enumerable
    ex: rescued exceptions
    f: files and file names
    i,j: indexes
    k: the key part of a hash entry
    m: methods
    o: any object
    r: return values of short methods
    s: strings
    v: any value
    v: the value part of a hash entry
    x,y,z: numbers

    And in general, the first letter of the class name if all objects are of that type.

    * When using **inject** with short blocks, name the arguments **|a, e|** (mnemonic: accumulator, element)
    * When defining binary operators, name the argument "other".

    ```Ruby
    def +(other)
    # body omitted
    end
    ```

    * Prefer **map** over *collect*, **find** over *detect*, **find_all** over *select*, **size** over *length*. This is not a hard requirement, though - if
    the use of the alias enhances readability - it's ok to use it.
    ## Comments
    * Write self documenting code and ignore the rest of this section.
    * _"Good code is its own best documentation. As you’re about to add
    a comment, ask yourself, ‘How can I improve the code so that
    this comment isn’t needed?’ Improve the code and then document
    it to make it even clearer."_ -- Steve McConnell
    * Comments longer than a word are capitalized and use punctuation. Use two spaces after periods.
    * Avoid superfluous comments.
    ```Ruby
    # bad
    counter += 1 # increments counter by one
    ```
    * Keep existing comments up-to-date - no comment is better than an
    outdated comment.
    * Avoid writing comments to explain bad code. Try to refactor the code to make it self-explanatory.
    ## Misc
    * Write **ruby -w** safe code.
    * Avoid hashes-as-optional-parameters. Does the method do too much?
    * Avoid long methods (longer than 10 LOC). Ideally most methods will be shorter than 5 LOC. Empty line do not contribute to the relevant LOC.
    * Avoid long parameter lists (more than 3-4 params).
    * Use **def self.method** to define singleton methods. This makes the methods more resistent to refactoring changes.
    ```Ruby
    class TestClass
    # bad
    def TestClass.some_method
    # body omitted
    end
    # good
    def self.some_other_method
    # body omitted
    end
    end
    ```
    * Add "global" methods to Kernel (if you have to) and make them private.
    * Avoid **alias** when **alias_method** will do.
    * Use **OptionParser** for parsing complex command line options and
    **ruby -s* for trivial command line options.
    * Avoid needless metaprogramming.
    ## Design
    * Code in a functional way, avoid mutation when it 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. See this [article](http://www.erlang.se/doc/programming_rules.shtml#HDR11) for more details.
    * Keep the code simple (subjective, but still...). Each method should have a single well-defined responsibility.
    * Avoid more than 3 Level 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 it should not be 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 the points listed here in this guidelines.
    * Use common sense.
    Feel free to open tickets or send pull requests with
    improvements. Thanks in advance for your help!
    (forked from https://github.com/bbatsov/ruby-style-guide/)