1.理解Ruby中的true
2.所有对象的值都可能是nil
3.避免使用ruby中存在的古怪的perl风格语法
4.注意常量是可变的
5.留意运行时警告
1.理解Ruby中的true
#1.除了false和nil之外的所有值都表示为真值
#2.使用nil?来判断是否为nil
nil.nil? #=>true
false.nil? #=>false
#使用比较时,false需要放在“==”表达式的左边,因为“==”是BasicObject的方法,能被普通类继承和改写
class Bad
def ==(other)
true
end
end
false == Bad.new #=>false
Bad.new == false #=>true,Bad.new和false相当于调用了“==”方法
#3.true、false、nil都是其单例的唯一实例化对象,可以直接调用其实例方法
true.class #TrueClass
false.class #FalseClass
nil.class #NilClass
2.所有对象的值都可能是nil
#开发中常见的问题
undefined method "xx" for nil:NilClass(NoMethodError)
#通过下面的几种方式来排除nil, 判断,转换和去除
#判断 nil?方法
person.save if person
person.save if !person.nil?
person.save unless person.nil?
#转换 将对象转换为期望的类型
nil.to_s #=> " "
nil.to_a #=> []
nil.to_i #=> 0
nil.to_f #=> 0.0
#去除 Array#compact方法返回去掉所有nil元素的方法的接受者的副本
name = [first, middle, last].compact.join(" ")
3.避免使用ruby中存在的古怪的perl风格语法
#1.使用String#match替代String#=~,前者将匹配信息以MatchData对象返回
def extract_error(message)
if message =~ /^ERROR:\s+(.+)$/
$1
else
"no error"
end
end
def extract_error(message)
if m = message.match(/^ERROR:\s+(.+)$/)
m[1]
else
"no error"
end
end
#2.使用更长,更表意的全局变量的别名,比如使用$LOAD_PATH代替$:
#3.避免使用隐式读写全局变量$_的方法(不懂,备注)
while readline
print if ~ /^ERROR:/
end
4.注意常量是可变的
#ruby中的常量是可变的,如果改变常量会出现警告,但是还是会改变成功
Demo = "demo"
Demo = "hello" #warning: already initialized constant Demo
#对单个常量执行freeze, 进行赋值的过程中也会成功
Demo = "demo"
Demo.freeze
Demo = "hello" #warning: already initialized constant Demo
#对于在moduel中的常量,可以通过freeze这个module来冻结常量,使得其不能被改变
module Defaults
TIMEOUT = 5
end
Defaults.freeze
Defaults::TIMEOUT = 10 #出现错误
#对数组进行freeze是进行浅冻结,这样子不可以增减元素,但是可以改变元素
array = ["a", "b"]
array.freeze
array << "c" #失败,因为该数组进行了freeze
array.each{|obj| obj << "c"} #成功,值为["ac", "bc"],说明值并没有进行freeze
#对数组和数组中的元素都进行freeze,可以达到如上完全freeze数组的目的
array.each(&:freeze).freeze #对数组进行freeze的同时对数组内的元素freeze
array.each{|obj| obj << "c"} #失败
5.留意运行时警告
ruby -w script.rb