Home

Awesome

Ruby 代码风格指南

这是 Airbnb 的 Ruby 代码风格指南

指南灵感来自于 Github 的指南Bozhidar Batsov 的指南

Airbnb 也在维护 JavaScript 风格指南

内容表 (Table of Contents)

  1. 空格 (Whitespace) 1. 缩进 (Indentation) 1. 行内 (Inline) 1. 换行 (Newlines)
  2. 行宽 (Line Length)
  3. 注释 (Commenting) 1. 文件级/类级 注释 (File/class-level comments) 1. 函数注释 (Function comments) 1. 块级和行内注释 (Block and inline comments) 1. 标点符号, 拼写和语法 (Punctuation, spelling, and grammar) 1. 待办注释 (TODO comments) 1. 注释掉的代码 (Commented-out code)
  4. 方法 (Methods) 1. 方法定义 (Method definitions) 1. 方法调用 (Method calls)
  5. 条件表达式 (Conditional Expressions) 1. 关键字 (Conditional keywords) 1. 三元操作符 (Ternary operator)
  6. 语法 (Syntax)
  7. 命名 (Naming)
  8. 类 (Classes)
  9. 异常 (Exceptions)
  10. 集合 (Collections)
  11. 字符串 (Strings)
  12. 正则表达式 (Regular Expressions)
  13. 百分比字面量 (Percent Literals)
  14. Rails 1. 范围 (Scopes)
  15. 保持一致 (Be Consistent)

空格 (Whitespace)

缩进 (Indentation)

行内 (Inline)

换行 (Newlines)

行宽 (Line Length)

注释 (Commenting)

虽然写注释很痛苦, 但是对于保持代码可读非常重要
下面的规则描述了你应该怎么写注释, 以及写在哪里。
但是记住:注释虽然非常重要, 但是最好的注释是代码本身。
直观的变量名本身就是注释, 比起起一个奇怪的名字,然后用注释解释要好得多

当写注释时,为你的观众去写:下一个贡献者需要理解你的代码。
请慷慨一些 - 下一个可能就是你自己!

Google C++ 风格指南

这一部分的指南从 Google C++Python 风格指南那边借鉴了很多。

文件/类 级别的注释 (File/class-level comments)

每个类的定义都应该带些注释, 说明它是干什么的, 以及怎么用它。

如果文件里没有任何 class, 或者多于一个 class, 顶部应该有注释说明里面是什么。

# Automatic conversion of one locale to another where it is possible, like
# American to British English.
module Translation
  # Class for converting between text between similar locales.
  # Right now only conversion between American English -> British, Canadian,
  # Australian, New Zealand variations is provided.
  class PrimAndProper
    def initialize
      @converters = { :en => { :"en-AU" => AmericanToAustralian.new,
                               :"en-CA" => AmericanToCanadian.new,
                               :"en-GB" => AmericanToBritish.new,
                               :"en-NZ" => AmericanToKiwi.new,
                             } }
    end

  ...

  # Applies transforms to American English that are common to
  # variants of all other English colonies.
  class AmericanToColonial
    ...
  end

  # Converts American to British English.
  # In addition to general Colonial English variations, changes "apartment"
  # to "flat".
  class AmericanToBritish < AmericanToColonial
    ...
  end

所有文件,包括数据和配置文件,都应该有文件级别(file-level)的注释。

# List of American-to-British spelling variants.
#
# This list is made with
# lib/tasks/list_american_to_british_spelling_variants.rake.
#
# It contains words with general spelling variation patterns:
#   [trave]led/lled, [real]ize/ise, [flav]or/our, [cent]er/re, plus
# and these extras:
#   learned/learnt, practices/practises, airplane/aeroplane, ...

sectarianizes: sectarianises
neutralization: neutralisation
...

函数注释 (Function comments)

函数声明的前面都应该有注释,描述函数是做什么的,以及怎么用。
这些注释应该是 描述性的(descriptive) 比如 ("Opens the file")
而不是 命令式的(imperative) 比如 ("Open the file");
注释描述这个函数,而不是告诉这个函数应该做什么。
总的来说,函数前面的注释并不负责解释函数是怎么做到它提供的功能的。
解释功能怎么实现的注释,应该零散的分布在函数内部的注释里。

每个函数都应该提到输入和输出是什么,除非碰到以下情况:

你喜欢什么格式都行。在 Ruby 里两种常见的格式是 TomDocYARD
你也可以直接简洁明了的写出来,比如这样:

# Returns the fallback locales for the_locale.
# If opts[:exclude_default] is set, the default locale, which is otherwise
# always the last one in the returned list, will be excluded.
#
# For example:
#   fallbacks_for(:"pt-BR")
#     => [:"pt-BR", :pt, :en]
#   fallbacks_for(:"pt-BR", :exclude_default => true)
#     => [:"pt-BR", :pt]
def fallbacks_for(the_locale, opts = {})
  ...
end

块级和行内注释 (Block and inline comments)

这个部分有点小麻烦. 如果你下次 code review 需要解释这些代码的话, 你现在就应该写注释。
复杂的操作应该把注释写在前面。
单行的不太容易理解的代码, 注释应该写在代码后面。

def fallbacks_for(the_locale, opts = {})
  # dup() to produce an array that we can mutate.
  ret = @fallbacks[the_locale].dup

  # We make two assumptions here:
  # 1) There is only one default locale (that is, it has no less-specific
  #    children).
  # 2) The default locale is just a language. (Like :en, and not :"en-US".)
  if opts[:exclude_default] &&
      ret.last == default_locale &&
      ret.last != language_from_locale(the_locale)
    ret.pop
  end

  ret
end

在另一方面,永远不要在注释里描述代码。你要假设读代码的人对这门语言的了解比你知道的多。

<a name="no-block-comments"></a>相关的一个事儿:不要用块级注释,他们前面没有空格,不方便一眼认出来是注释。 <sup>[link]</sup>

# 错误
=begin
comment line
another comment line
=end

# 正确
# comment line
# another comment line

标点符号, 拼写和语法 (Punctuation, spelling, and grammar)

要注意注释里的标点符号, 拼写和语法;
注释写得好读起来也容易。

注释应该和叙述文 (narrative text) 一样易读 (readable),
有着正确的大小写和标点符号。 在很多情况下。 完整的句子比句子碎片容易读得多。
短的注释, 比如跟在代码后面的, 可以不那么正式, 但风格应该一致。

虽然在提交代码时, 别人指出你在应该用分号的地方用了逗号, 这种小事蛮折磨人的.
但重要的是源代码应该保持高度的清晰和可读. 正确的标点符号, 拼写, 和语法非常重要.

待办注释 (TODO comments)

当代码是临时解决方案,够用但是并不完美时,用 TODO 注释。

TODO 应该全大写, 然后是写这个注释的人名, 用圆括号括起来, 冒号可写可不写。
然后后面是解释需要做什么,统一 TODO 注释样式的目的是方便搜索。
括号里的人名不代表这个人负责解决这个问题, 只是说这个人知道这里要解决什么问题.
每次你写 TODO 注释的时候加上你的名字。

  # 错误
  # TODO(RS): Use proper namespacing for this constant.

  # 错误
  # TODO(drumm3rz4lyfe): Use proper namespacing for this constant.

  # 正确
  # TODO(Ringo Starr): Use proper namespacing for this constant.

注释掉的代码 (Commented-out code)

方法 (Methods)

方法定义 (Method definitions)

方法调用 (Method calls)

应该用 圆括号 的情况:

不论什么情况:

条件表达式 (Conditional Expressions)

关键字 (Conditional keywords)

三元操作符 (Ternary operator)

语法 (Syntax)

命名 (Naming)

类 (Classes)

异常 (Exceptions)

集合 (Collections)

字符串 (Strings)

正则表达式 (Regular Expressions)

百分比字面量 (Percent Literals)

Rails

范围 (Scopes)

保持一致 (Be Consistent)

在你编辑某块代码时,看看周围的代码是什么风格。
如果它们在数学操作符两边都放了空格,那么你也应该这样做。
如果它们的代码注释用 # 井号包成了一个盒子, 那么你也应该这样做。

风格指南存在的意义是 让看代码时能关注 "代码说的是什么"。
而不是 "代码是怎么说这件事的"。这份整体风格指南就是帮助你做这件事的。
注意局部的风格同样重要。如果一个部分的代码和周围的代码很不一样。
别人读的时候思路可能会被打断。尽量避免这一点。

Google C++ Style Guide