前言
本文是使用Ruby语言进行项目开发的编码规约。实际开发中推荐以此作为标准进行Ruby编码。
1. 代码整形
1.1 缩进
为了便于阅读程序,需要进行适当的缩进。缩进宽度为2个空格。(不要使用Tab,因为在不同环境下Tab的宽度是不一样的)
正确的例子:
if x > 0 if y > 0 puts "x > 0 && y > 0" end end
1.2 一行的长度
一行代码的长度不要超过80个半角字符。
1.3 空行
1.3.1 类与类之间要插入空行进行分隔。
正确的例子:
class Foo ... end class Bar ... end
错误的例子:
class Foo ... end class Bar ... end
1.3.2 类成员之间要用空行分隔。注意:在第一个成员前,和最后一个成员后不要插入空行。
正确的例子:
class Foo attr :bar def baz ... end def quux .. end end
错误的例子:
class Foo attr :bar def baz ... end def quux ... end end
2. 注释
2.1 用英语注释
注释只能使用英语,并尽量简洁明了。(如果无法用简单的英语说明,那么要反思是否代码写得太复杂了)
2.1 方法中不要加注释
方法定义中不要添加注释。(如果需要添加注释,那么需要考虑该方法是否需要重构。另一方面,如果你认为“我自己以后可能会混乱”,则不要犹豫,添加注释。
正确的例子:
# use ',' to split the input str and return. def split_csv(str) return str.split(/,/) end
3. 语法相关的规约
3.1 类的成员
按照如下的顺序描述类的成员。
- include, require
- 定义常量
- 定义类变量和实例变量
- 定义public的类方法
- 定义accessor
- 定义initialize
- 定义public的instance方法
- 定义protected的类方法
- 定义protected的accessor
- 定义protected的instance方法
- 定义private的类方法
- 定义private的accessor
- 定义private的instance方法
- 定义嵌套类
3.2 关于accessor
在定义accessor时,使用 attr_accessor, attr_reader, attr_writer (不要使用 attr)
3.3 关于method
如非必要,method应该控制在20行以内。共通功能部分要提取为module。
method的参数必须用括号(method名和括号之间不要加空格)。但当没有参数时,可省略括号。
正确的例子:
def foo(x, y) ... end def foo ... end
错误的例子:
def foo x, y ... end def foo() ... end
3.4 类方法
定义类方法时,使用 self
正确的例子:
class Foo def self.foo ... end end
错误的例子:
class Foo def Foo.foo ... end end
3.5 方法调用
方法调用时,参数必须用括号。但当没有参数时,可省略括号。
特例:print, puts, p 可以省略参数的括号。
正确的例子:
foo(1, "abc") obj.foo(1, "abc") bar print "x = ", x, "\n"
错误的例子:
foo 1, "abc" obj.foo 1, "abc" bar()
3.6 block
block一般使用 do ... end
正确的例子:
foo(x, y) do ... end x = bar(y, z) do ... end
错误的例子:
foo(x, y) { ... } x = bar(y, z) { ... }
但是,当作为迭代器使用时,用{ ... }
正确的例子:
s = ary.collect { |i| i.to_s }.join(",")
错误的例子:
s = ary.collect do |i| i.to_s end.join(",")
3.7 return
当方法需要返回值时,必须使用return。同时,省略return的括号。
正确的例子:
def add(x, y) return x + y end
错误的例子:
def add(x, y) x + y end def add(x, y) return(x + y) end
3.8 yield
-
3.9 条件分支
if语句后不需要 then。
不做 "== true" 这样的判断。(因为在Ruby中,true并不是唯一的真值)
if !x 这样的情况,替换为 unless x。使用unless时,不能用else。如果条件非常简单,一行就能写完,可以使用 if/while 等修饰符。
正确的例子:
if x > 0 puts "x > 0" else puts "x <= 0" end unless x puts "x is false" end puts "x is true" if x
错误的例子:
if x > 0 then puts "x > 0" end unless x puts "x is false" else puts "x is true" end puts "foo && bar && baz && quux" if foo && bar && baz && quux
能用case时,使用case。case后面不需要 then。
正确的例子:
case x when 1 ... when 2 ... end
错误的例子:
if x == 1 ... elsif x == 2 ... end case x when 1 then ... when 2 then ... end
不要用带有条件分支的表达式赋值。
正确的例子:
if x > 0 msg = "x > 0" else msg = "x <= 0" end
错误的例子:
msg = if x > 0 "x > 0" else "x <= 0" end
3.10 循环
while循环后不需要do。当出现 while !x 等情况下,替换为 until x。
正确的例子:
while cond ... end until cond ... end
错误的例子:
while cond do ... end
死循环使用loop。
正确的例子:
loop do ... end
错误的例子:
while true ... end
3.11 运算符
在运算符的两端添加空格。
由于字符串拼接等造成行较长时,两端可以不添加空格,但要保证风格统一。
3.12 逻辑运算符
逻辑运算使用 ! && ||,不要使用 not and or
3.13 三项运算符
除非不影响代码可读性,否则尽量不要使用三项运算符,尤其是使用括号等复杂条件的情况以及多行时。
3.14 类型的判断
原则上不使用 kind_of? 或者 isa?,推荐使用 DuckTyping
3.15 字符串
字符串一般使用"..."。但是,当有不希望解释的特殊字符时,使用'...'。原则上不使用here document。
3.16 库文件
库文件的末尾用 if __FILE__ == $0 括起,并推荐写测试case 或者 sample 程序。
4. 命名规约
4.1 整体
- 原则上不省略单词。
- 在作用范围较小的循环内,变量名按照i,j,k的顺序使用。
- 对于作用范围较小的变量名,可以省略类名。 (例: eo = ExampleObject.new)
4.2 类名、模块名
类名、模块名的首字母大写,不使用"_"等分隔符。但是,HTTP等单词缩写需要全部大写。
正确的例子:
ExampleClass HTTPClient
错误的例子:
Example_Class EXAMPLE_CLASS HttpClient HTTPclient HTTP_Client
4.3 方法名
方法名全部小写,内部用"_"分隔。方法名中的英文使用动词原形。
正确的例子:
add_something
错误的例子:
addsSomething Add_Something
对于返回真假值的方法名,动词或者形容词上添加"?",形容词不添加 "is_"。
正确的例子:
visible?
错误的例子:
is_visible is_visible?
4.4 常量名
类名、模块名以外的常量名全部用大写,内部用"_"分隔。
正确的例子:
EXAMPLE_CONSTANT
4.5 変量名
变量名全部用小写,内部用"_"分隔。
正确的例子:
tmp local_variable @instance_variable $global_variable
4.6 文件名
文件名全部用小写,内部用"_"分隔。
推荐:用文件中的主要类名转换后作为文件名。(用模块作为名称空间时,使用目录表现层次结构。)
正确的例子:
foo.rb # クラスFooを定義 foo-bar.rb # クラスFooBarを定義 foo/bar-baz.rb # クラスFoo::BarBazを定義