刚开始接触RoR时,我经常将 nil?, empty? blank? 方法混淆,用错. 这导致了当我在调用它们时处理条件判断所遇到的麻烦.
而我之前对PHP, Actionscript的理解对此不仅没有帮助,反而让我变得更困扰. 这些语言的类似方法返回的结果与Ruby确是相反的.
我想通过一些代码的练习,能够加深我对这些相似方法的理解.
先从nil?方法开始.
.nil? 方法是对于Ruby中任意对象皆可调用的方法, 用于检测目标对象是否存在,有效. 在条件分支语句中当你调用一个对象之前
事先对它进行有效性进行判断是很有帮助的. Ruby中, 所有类均继承自Object. nil? 是来自于Object的方法, 因此除了特殊情况(
对它的重写, 相信一般也不会这么做), 所有类均会拥有此方法.
为更好理解Ruby是怎样表示一个不存在的对象, 我们需要看一变量 nil. 在其它的语言中,同样地被记作 NULL或null. 根据语言
对"空"的理解, NULL不会指向任何东西. Ruby恰恰在这点上与这些不同, Ruby拥有一个真实存在的类NilClass , 所以nil有其自身的方法,
尽管这在其它语言的角度看来有些不对劲,
nil.nil?
=> true
当我们访问一个不存在的对象,或者正好将一个目标的值赋为nil, 我们会得到一个NilClass的单键实例对象 -- nil. 见下面的几个例子:
cool_people = {:conan_the_destroyer => "man", :red_sonja => "woman"}
cool_people[:george_bush_II]
=> nil
cool_people[:george_bush_II].class
=> NilClass
cool_people[:george_bush_II].nil?
=> true
cool_people[:conan_the_destroyer].nil?
=> false
test_var = nil
test_var.nil?
=> true
[].nil?
=> false
"".nil?
=> false
0.nil?
=> false
false.nil?
=> false
备注
# 访问不存在hash键值
# 因为对应的key-value是在原hash中存在的, 返回false
# 这个请注意 空的对象 空数组 或者是 长度为0的字符串 不等于nil.
下面我们来看看 empty?
与nil?方法不同的是, empty? 仅适用于一部分Ruby对象. String类, Hash类,Array类均可以调用该方法. 当对象调用它时, 会判断该目标是否拥有非空的值, 返回逻辑值true或false.
["Larry", "Curly", "Moe"].empty?
=> false
[""].empty?
=> false
[].empty?
=> true
{}.empty?
=> true
"".empty?
=> true
0.empty?
=> NoMethodError: undefined method `empty?' for 0:Fixnum
test_var2 = nil
test_var2.empty?
= > NoMethodError: undefined method `empty?' for nil:NilClass
上面的最后一个例子能够说明当们如此操作时会有什么样结果 (0 0 )
dog = {:name => "Beauregard"}
puts "What kind?" if dog[:breed].empty?
=> NoMethodError: undefined method `empty?' for nil:NilClass
# Use nil? instead.
puts "What kind?" if dog[:breed].nil?
=> What kind?
备注: 因为 dog[:breed] 不存在得到nil, 而nil应该用 nil.nil? 的方式去判断 非 .empty?
Rails中会常用到的blank? 方法
blank?方法是Rails而非Ruby中的方法. 基本上它实现了nil? empty?的作用. 下面是来自Rails API文档中的介绍:“An object is blank if it‘s false, empty, or a whitespace string.
For example, "", " ", nil, [], and {} are blank.”
举例来说, 我经常会在模型中赋值的场景调用blank?方法. 回想之前的例子-- dog哈希表, 我们可以这样来简化检验值
script/console >>
dog = {:name => "Beauregard"}
puts "What kind?" if dog[:breed].blank?
=> What kind?
dog = {:name => "Beauregard", :breed => ""}
puts "What kind?" if dog[:breed].blank?
=> What kind?
可以看到 .blank? 的结果 相当于 .ni? + .empty?
如果还有哪里不够清楚,请与我讨论:)Let me know if I missed anything.