Skip to content

Instantly share code, notes, and snippets.

@christhekeele
Last active August 29, 2015 13:56
Show Gist options
  • Save christhekeele/9127902 to your computer and use it in GitHub Desktop.
Save christhekeele/9127902 to your computer and use it in GitHub Desktop.
My personal collection of styleguides, with rationalizations for most preferences.

Styleguides

These are my personally cultivated styleguides for different types of text (normally code or markup).

They're less about common conventions (ie. put single spaces between sentences or new lines between different contexts) and more about what syntax features to prefer or avoid in which contexts. As such, they expect the reader to be familiar with the language or markup in question. They are not suitable introductory material to a syntax.

Comments and discussion are welcome, otherwise I'd just keep these in my head instead of on a publicly available forum. I especially invite you to try and change my mind: these, like all opinions and code, are works in progress; not absolutes.

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in the OXFORD ENGLISH DICTIONARY.

List of Styleguides

Code

As a programmer, I have general opinions about code.

Code Styleguide

Code Indentation

  • Always use soft tabs.

    Unless you hate your fellow programmers, don't use hard tabs.

  • Always use two spaces when indenting in languages that require block-closing (whitespace-insensitive) constructs.

    ie. most languages.

  • Always use four spaces when indenting in languages that don't require block-closing (whitespace-sensitive) constructs.

    ie. Python, Coffeescript

  • Always start new lines and indent for new tags in tag-based markup langages.

    ie. HTML. Use 2 spaces as noted above.

Markdown

Markdown is my markup language of choice.

Markdown Styleguide

Markdown Line Breaks

  • Do not manually wrap continuations of text (ie. every 80 characters).

    Instead let your text editor, and to the extent available, its settings, auto-word wrap.

    This respects the behaviors of other readers' text editors and personal settings when viewing your raw composition, and allows portability between traditional markdown and GitHub-flavored markdown's newline behavior.

    Prefer spacing out paragraphs with two new lines.

    This allows portability between traditional and GitHub-flavored markdown.

Markdown Headers

  • Prefer underlined h1 (===) and h2 (---) headers.

    This allows these parts of your composition stand out in plain text and organically groups sections visually.

  • Always use the same number of underlined header characters as your header is long.

    This is visually more readable when consulting the raw composition than a fixed quantity.

    Example:

    BAD!
    ======
    
    WORSE!
    ===
    
    GOOD
    ====

Markdown Lists

  • Prefer - notation for denoting unordered list items over * or +.

    This differentiates lists from emphasis marks (*/**) and headers (#), which clash with +.

  • Always use hanging indents for multiline list items.

    This makes it easier to convert them to nested lists or separate list items later and aids readability.

  • Prefer spacing out sections of multiline list items with two new lines.

    This makes sections more apparent.

  • Always start ordered list items with 1..

    The way markdown works, it starts at 1. anyways. The original markdown specification notes that this behavior may change (allowing you to choose where the list starts), so starting with 1. is future-proof.

  • Always use 1. for all ordered list items.

Markdown auto-increments list items from their start, regardless of the number used. Make things easier to insert/delete later and only ever use 1..

Markdown Code

  • Prefer fenced code blocks (```) when available, especially in longer compositions.

    This prevents their character from being masked by other indentation-sensitive constructs such as multi-line list items, and allows easy syntax highlighting when available.

Ruby

Ruby is my programming language of choice.

Ruby Styleguide

Ruby Indentation

  • Always indent two spaces, soft tabs.

  • Prefer defining class methods in a block with class << self.

    Example:

    # BAD!
    class Klass
      def self.kname
        # ...
      end
    end
    
    # GOOD
    class Klass
      class << self
        def kname
          # ...
        end
      end
    end

    The additional indentation highlights the important difference between these methods and instance methods. It's harder to miss them, and easy to glaze over the self in def self.kname.

    This also encourages you to group class methods together, avoiding fragmentation in classes.

  • Always dedent public, protected, and private declarations.

    # BAD!
    class Klass
      def method
        # ...
      end
      private
      def other
        # ...
      end
    end
    
    # WORSE!
    class Klass
      def method
        # ...
      end
      private
        def other
          # ...
        end
    end
    
    # GOOD
    class Klass
      def method
        # ...
      end
    private
      def other
        # ...
      end
    end

    Keeping the declaration at the same indent level allows this construct to be confused with class method invocations. Furthermore, deeper indentation of methods after these declarations suggests they are individually somehow different from the standard public ones. Because of send, this is an illusion in ruby.

    Best to showcase the important intention of the declaration by codenting it with the class, and emphasize the simlilarity of the following methods with others by keeping the indentation of your defs constant. This works well with the always put class methods in class << self blocks rule above, such that deeper-indented defs are always indicative of class methods.

Ruby Modules

  • Always deeply declare namespaces.

    Example:

    # BAD!
    class Name::Space::Example
      # ...
    end
    
    # GOOD
    module Name
      module Space
        class Example
          # ...
        end
      end
    end

    This allows the order that namespaced files are required in to be changed seamlessly. It also makes you more aware of the depth of your namespaces.

    It also alerts you to when a class is serving double duty as a namespace, making you more aware of the context of the namespace you're operating in.

    One valid exception is when you're monkey-patching an external library. In this case one-liner namespaces may be used, as the type (and superclass) of each constant can be considered an implementation detail.

    The exception to this exception is when you're adding a new constant to an external library's namespace (rather than monkey patching an existing one). In this situation it is even more important to understand the context of the heirarchy you're extending.

Ruby Methods

  • Never use parentheses for method definitions without parameters.

    Example:

    # BAD!
    def foo()
      # ...
    end
    
    # GOOD
    def foo
      # ...
    end

    This highlights the fact the method can be used as a bareword, without any parenthesis on invocation.

    This is desirable, because using barewords as often as possible makes it super easy to refactor the location of your code, check out Avdi Grimm's great screencast for examples of this in work.

  • Always use parentheses (with a few exeptions below) for method definitions with parameters.

    Example:

    # BAD!
    def foo bar
      # ...
    end
    
    # GOOD
    def foo(bar)
      # ...
    end

    This highlights the fact that this is a normal method, with no special properties–it isn't parameterless like above, nor a special Ruby hook like below.

  • Don't use parentheses for special ruby hooks.

    Example:

    # BAD!
    def ==(other)
      # ...
    end
    
    # GOOD
    def == other
      # ...
    end
    
    # BAD!
    def extended(base)
      # ...
    end
    
    # GOOD
    def extended base
      # ...
    end

    This highlights the fact that this is a special ruby method. In the case of operators, it makes the method definition look more inline with its usage. In the case of included/extended/prepended/inherited hooks, it makes it look more like the invocation of the directives that trigger them.

  • Always inline super calls alongside the definition of ruby hooks.

    Example:

    # BAD!
    def extended base
      super
      # ...
    end
    
    # GOOD
    def extended base; super
      # ...
    end

    When using these special hooks, there's no way to tell if other libraries rely on their functionality. Therefore, it's vital to always make a super call–normally before your extension of their functionality–or things may break now if not later. Getting into the habit of inlining the super call reminds you that these hooks should always call super, to the extent of that being a required part of their definition.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment