语法 (Syntax)
永远不要用
for
,除非有非常特殊的理由。
绝大部分情况都应该用each
。for
是用each
实现的(所以你间接加了一层),
但区别是 -for
不会有新 scope (不像each
) 里面定义的变量外面可见。[link]arr = [1, 2, 3]
# 错误
for elem in arr do
puts elem
end
# 正确
arr.each { |elem| puts elem }
单行的情况下, 尽量用{...}
而不是do...end
。
多行的情况下避免用{...}
.
对于 “control flow” 和 “方法定义”(举例: 在 Rakefiles 和某些 DSLs 里) 总是用do...end
。
方法连用(chaining)时 避免使用do...end
。[link]names = ["Bozhidar", "Steve", "Sarah"]
# 正确
names.each { |name| puts name }
# 错误
names.each do |name| puts name end
# 正确
names.each do |name|
puts name
puts 'yay!'
end
# 错误
names.each { |name|
puts name
puts 'yay!'
}
# 正确
names.select { |name| name.start_with?("S") }.map { |name| name.upcase }
# 错误
names.select do |name|
name.start_with?("S")
end.map { |name| name.upcase }
有些人会说多行连用(chaining) 用
{...}
符号 其实也没那么难看, 但他们应该问问自己这代码真的可读吗, 而且 block 里的内容是否可以抽出来弄好看些.尽可能用短的自赋值操作符 (self assignment operators)。[link]
# 错误
x = x + y
x = x * y
x = x**y
x = x / y
x = x || y
x = x && y
# 正确
x += y
x *= y
x **= y
x /= y
x ||= y
x &&= y
避免用分号。 除非是单行 class 定义的情况下。 而且当使用分号时, 分号前面不应该有空格。[link]
# 错误
puts 'foobar'; # 多余的分号
puts 'foo'; puts 'bar' # 两个表达式放到一行
# 正确
puts 'foobar'
puts 'foo'
puts 'bar'
puts 'foo', 'bar' # this applies to puts in particular
:: 的使用场景是引用常量,(比如
classes 和 modules 里的常量) 以及调用构造函数 (比如 Array() 或者 Nokogiri::HTML())。
普通方法调用就不要使用 :: 了。[link]# 错误
SomeClass::some_method
some_object::some_method
# 正确
SomeClass.some_method
some_object.some_method
SomeModule::SomeClass::SOME_CONST
SomeModule::SomeClass()
尽量避免用
return
。
[link]# 错误
def some_method(some_arr)
return some_arr.size
end
# 正确
def some_method(some_arr)
some_arr.size
end
条件语句里不要用返回值[link]
# 错误 - shows intended use of assignment
if (v = array.grep(/foo/))
...
end
# 错误
if v = array.grep(/foo/)
...
end
# 正确
v = array.grep(/foo/)
if v
...
end
请随意用
||=
来初始化变量。
[link]# 把 name 赋值为 Bozhidar, 仅当 name 是 nil 或者 false 时
name ||= 'Bozhidar'
不要用
||=
来初始化布尔变量。
(想象下如果值刚好是false
会咋样.)[link]# 错误 - would set enabled to true even if it was false
enabled ||= true
# 正确
enabled = true if enabled.nil?
当调用 lambdas 时,明确使用
.call
。
[link]# 错误
lambda.(x, y)
# 正确
lambda.call(x, y)
避免使用 Perl 风格的特殊变量名
( 比如$0-9
,$
, 等等. ). 因为看起来蛮神秘的. 建议只在单行里使用。建议用长名字, 比如$PROGRAM_NAME
.[link]当一个方法块只需要 1 个参数,而且方法体也只是读一个属性, 或者无参数的调用一样方法,这种情况下用
&:
.
[link]# 错误
bluths.map { |bluth| bluth.occupation }
bluths.select { |bluth| bluth.blue_self? }
# 正确
bluths.map(&:occupation)
bluths.select(&:blue_self?)
当调用当前实例的某个方法时, 尽量用
some_method
而不是self.some_method
。[link]# 错误
def end_date
self.start_date + self.nights
end
# 正确
def end_date
start_date + nights
end
在下面 3 种常见情况里, 需要用, 而且应该用
self.
:- 当定义一个类方法时:
def self.some_method
. - 当调用一个赋值方法 (assignment method) 时,左手边 应该用 self, 比如当 self 是 ActiveRecord 模型然后你需要赋值一个属性:
self.guest = user
. - 指向 (Referencing) 当前实例的类:
self.class
.