异常 (Exceptions)
不要把异常用于控制流里 (flow of control)
[link]# 错误
begin
n / d
rescue ZeroDivisionError
puts "Cannot divide by 0!"
end
# 正确
if d.zero?
puts "Cannot divide by 0!"
else
n / d
end
避免捕捉
Exception
这个大类的异常
[link]# 错误
begin
# an exception occurs here
rescue Exception
# exception handling
end
# 正确
begin
# an exception occurs here
rescue StandardError
# exception handling
end
# 可以接受
begin
# an exception occurs here
rescue
# exception handling
end
传 2 个参数调 raise 异常时不要明确指明
RuntimeError
。尽量用 error 子类这样比较清晰和明确。[link]# 错误
raise RuntimeError, 'message'
# 正确一点 - RuntimeError 是默认的
raise 'message'
# 最好
class MyExplicitError < RuntimeError; end
raise MyExplicitError
尽量将异常的类和讯息两个分开作为
raise
的参数,而不是提供异常的实例。[link]# 错误
raise SomeException.new('message')
# 注意,提供异常的实例没办法做到 `raise SomeException.new('message'), backtrace`.
# 正确
raise SomeException, 'message'
# 可以达到 `raise SomeException, 'message', backtrace`.
避免使用 rescue 的变异形式。
[link]# 错误
read_file rescue handle_error($!)
# 正确
begin
read_file
rescue Errno:ENOENT => ex
handle_error(ex)
end