在学习 spec 的时候, 有个 eq 匹配器不是很理解, 所以查了下资料.
发现 ruby 中的比较函数, eql?
equal?
==
===
is_a?
kind_of?
instance_of?
傻傻分不清楚.
还有nil?
empty?
blank?
present?
几个函数. 也是比较容易引起混淆。
抽时间整理了下, 如果有错误, 欢迎指正.
一般情况下, 表现与 ==
相同. hash 里面 key 的比较, 就是采用的这个函数. 比如 {1.0 => 'a', 1 =>'b'}, 代表两个不同 key 值.
用来判定, 内存地址相同的对象, 使用的时候, 不应覆盖此方法. 有点类似于 JavaScript 中的 ===. 这里稍微引申下. a = 'b', b = 'b', a.equal?(b) 是返回 false 的, 因为定义变量 a, b 的时候, 生成了两个字符串变量 'b'. 他们的 object_id 是不一样的. 而如果 a = 'b', b = a, 此时相比则返回的是 true.
一般意义的值比较. 可以跨类使用. 比如 Float 和 Fixnum 类之间的比较. 1.0 == 1 结果是 true 的. 就是因为覆盖了相应的 == 方法.
case
里会调用该方法. 假设 b = A.new , 调用 A === b, 当 a 为 Class 对象的时候, 会调用 b.kind_of? a, 结果是返回 true 的, 但是 b === a, 则会返回 false. 同理, 当你 case b when A, 此时 when 里面的代码块也会执行, 其他情况下, 表现与 == 相同.
检查 一个对象是否是 Class 的一个实例. Class 可以不是 对象类的父类.
检查 一个对象是否是 Class 的一个实例. Class 不可以是 对象类的父类. 比如 a.instance_of B 可以翻译为 a.class == B
具体如下
1 === 1.0 # true
1 == 1.0 # true
1.eql?(1.0) # false
case 'string'
when String
p 'ok'
end
# ok
case String
when 'string'
p 'ok'
else
p false
end
# false
String === 'string' # true
'string'.kind_of?(String) # true
'string' === String # false
5.class # Fixnum
5.kind_of?(Integer) # true
5.instance_of(Integer) # false
================ 扩展============
只有 nil 的时候会返回 true.
nil 调用会报错, 检查一个对象为空. 字符串, 数组, hash 会检查 length 是否等于 0.
rails 的方法, 相当于 nil? || empty?
(这是错误的)
.blank? 还会在前者的基础上检查 字符串是否为空白, 空格, tab, 换行 都是空白.
ruby 中, 单引号定义的 字符串不会转义, 双引号定义的字符串会转义.
所以 '\n'.blank? 为 false, "\n".blank? 为 true
rails 的方法, 相当于 ! blank?
a = nil # if 时为 false
b = ''
c = ' '
d = []
e = {}
f = false # if 时为 false
g = true
h = [nil]
i = {temp: nil}
j = 0
k = 5
a.nil? # true
b.nil? # false
c.nil? # false
d.nil? # false
e.nil? # false
f.nil? # false
g.nil? # false
h.nil? # false
i.nil? # false
j.nil? # false
k.nil? # false
a.empty? # undefined method
b.empty? # true
c.empty? # false
d.empty? # true
e.empty? # true
f.empty? # undefined method
g.empty? # undefined method
h.empty? # false
i.empty? # false
j.empty? # undefined method
k.empty? # undefined method
# only used in rails
a.blank? # true
b.blank? # true
c.blank? # true
d.blank? # true
e.blank? # true
f.blank? # true
g.blank? # false
h.blank? # false
i.blank? # false
j.blank? # false
k.blank? # false
# only used in rails
a.present? # false
b.present? # false
c.present? # false
d.present? # false
e.present? # false
f.present? # false
g.present? # true
h.present? # true
i.present? # true
j.present? # true
k.present? # true