names = ['Bozhidar', 'Steve', 'Sarah']
# bad
names.each do |name|
puts name
end
# good
names.each { |name| puts name }
# bad
names.select do |name|
name.start_with?('S')
end.map { |name| name.upcase }
# good
names.select { |name| name.start_with?('S') }.map { |name| name.upcase }
有人会争论多行链式看起来和使用 {...} 一样工作,但是他们问问自己 - 这样的代码真的有可读性码并且为什么代码块中的内容不能被提取到美丽的方法中。
Consider using explicit block argument to avoid writing block
literal that just passes its arguments to another block. Beware of
the performance impact, though, as the block gets converted to a
Proc.
考虑使用明确的块参数来避免写入的块字面量仅仅传递参数的给另一个块。小心性能的影响,即使,
块被转换成了 Proc。
require 'tempfile'
# bad
def with_tmp_dir
Dir.mktmpdir do |tmp_dir|
Dir.chdir(tmp_dir) { |dir| yield dir } # block just passes arguments
end
end
# good
def with_tmp_dir(&block)
Dir.mktmpdir do |tmp_dir|
Dir.chdir(tmp_dir, &block)
end
end
with_tmp_dir do |dir|
puts "dir is accessible as parameter and pwd is set: #{dir}"
end
避免在不需要流的控制使用 return。
# bad def some_method(some_arr) return some_arr.size end # good def some_method(some_arr) some_arr.size end
避免在不需要的地方使用 self(它仅仅在调用一些 self 做写访问的时候需要)(It is only required when calling a self write accessor.)
# bad
def ready?
if self.last_reviewed_at > self.last_updated_at
self.worker.update(self.content, self.options)
self.status = :in_progress
end
self.status == :verified
end
# good
def ready?
if last_reviewed_at > last_updated_at
worker.update(content, options)
self.status = :in_progress
end
status == :verified
end
作为一个必然的结果,避免将方法(参数)放于局部变量阴影之下除非它们是相等的。
class Foo
attr_accessor :options
# ok
def initialize(options)
self.options = options
# both options and self.options are equivalent here
end
# bad
def do_something(options = {})
unless options[:when] == :later
output(self.options[:message])
end
end
# good
def do_something(params = {})
unless params[:when] == :later
output(options[:message])
end
end
end
不要在条件表达式里使用 = (赋值)的返回值,除非条件表达式在圆括号内被赋值。










