前言
本文是使用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を定義