我们知道,Ruby是动态语言。 静态类型:编译的时候就知道每一个变量的类型,因为类型错误而不能做的事情是语法错误。
动态类型:编译的时候不知道每一个变量的类型,因为类型错误而不能做的事情是运行时错误。 譬如说你不能对一个数字a写a[10]当数组用。
对于Ruby来说,当程序运行起来后,才有可能发现类型错误。
NoMethodError: undefined method ‘xxx’ for nil:NilClass 这是Ruby中最常见发生的Error
我们是否可以在写代码的时候,就选择更好的方式,来最大程度的避免的错误发生。
example1
name = first + last
如果 first 或 last 是 nil,则会报
NoMethodError: undefined method ‘’+’ for nil:NilClass
name = first.to_s + first.to_s
# better
name = "#{first}#{last}"
example2
def name(first, last, params = nil)
name = "#{first}#{last}-#{params[:nick_name]}"
end
当这样使用该方法时,则会报错
# wrong
name("Steven", "Curry") # => NoMethodError: undefined method `[]' for nil:NilClass
为了避免这种方法,你需要在name方法中加判断存在的逻辑,是否可以有更好的方式呢? 观察可以知道,params变量其实会是一个hash,所以,我们可以这样:
def name(first, last, params = {})
name = "#{first}#{last}-#{params[:nick_name]}"
end
name("Steven", "Curry") # => "StevenCurry-"
同理,当我们知道params是数组类型的时候,应该params = [] 用具体的一种类型的空表示,代替nil。可以避免
=> NoMethodError: undefined method ‘xxx’ for nil:NilClass
example3
别忘了try方法 在Rails中,任何对象都可以使用try方法
1.try(:a)
"name".try(:a)
String.try(:a)
try 方法中的参数是一个公有方法名,如果没有这个公有方法,则会返回nil值。注意,是公有方法。
try source code
def try(*a, &b)
if a.empty? && block_given?
yield self
else
public_send(*a, &b) if respond_to?(a.first)
end
end
可以发现,try方法可以加block,则会将self代入运行block。 或者调用public_send
"first".try do |name|
"#{name}_last"
end
# => "first_last"
未完待续