Effective Ruby 1 - 让自己熟悉 Ruby

让自己熟悉 Ruby

01 理解 Ruby 中的 True

  • 除了 falsenil 外所有的值都表示真值
  • 如果你需要区分 falsenil,可以使用 nil? 方法或 == 操作符并将 false 作为左操作对象

比如配置文件,false 表示应该被禁用,而 nil 表示没有显示定义,因此应该使用默认值。故我们需要区分 falsenil。而将 false 放在左边意味着 Ruby 会将表达式解析为 FlaseClass#== 方法的调用(该方法继承自 Object 类),如果 false 放在右边是有风险的,因为其它类可能覆盖 Object#== 方法。

02 所有对象的值都可能为 nil

  • 假设任何对象都可以为 nil,包括方法参数和调用方法的返回值
  • 将变量显示转换为期望的类型比时刻担心其为 nil 要容易的多

在产品环境我们经常遇到 undefined method 'fubar' for nil:NilClass (NoMethodError) 的错误。我们可以使用上面提到的方法来避免这个情况。

# 常见的防守写法
person.save if person

# 转换为期待的类型 nil.to_s #=> ''
def fix_title(title)
  title.to_s.capitalize
end

# 过滤掉 nil
name = [first, middle, last].compact.join(' ')

03 避免使用 Ruby 中古怪的 Perl 风格语法

  • 推荐使用 String#match 替代 String#=~
  • 使用更长、更表意的全局变量的别名,而非短的、古怪的名字。比如用 $LOAD_PATH 代替 $:,但是要注意这需要载入 English 库,Rails 已经载入这个库。
  • 避免使用隐式读写全局变量 $_ 的方法,比如 Kernel#print

04 留神,常量是可变的

  • 总是将常量冻结
  • 如果常量引用了一个集合对象,那么冻结这个集合及其所有元素
  • 要防止常量被重新赋值,可以冻结定义它的那个模块
# 即便冻结常量,仍然能被修改,只是会有警告信息,所以我们要冻结模块
module Default
  TIMEOUT = "a".freeze
end

Default::TIMEOUT = "b"
#=> warning: already initialized constant Default::TIMEOUT
#=> warning: previous definition of TIMEOUT was here
#=> "b"

module Default
  TIMEOUT = "a"
end
Default.freeze

Default::TIMEOUT = 'b'
#=> RuntimeError: can't modify frozen Module

05 留意运行时警告

  • 如果你写的是 Ruby 脚本,那么使用 -w 命令选项以启用编译和运行时的警告
  • 如果是 Rails 程序,可以在运行 Rake 测试的时候启用警告,后面几章会讲

如果觉得我的文章对您有用,请在支付宝公益平台找个项目捐点钱。 @Victor Oct 30, 2016

奉献爱心