Comparable是一个Module对象,如果要在类中使用Comparable,需要include Comparable和实现<=>方法。代码示例如下:
class SizeMatters
#步骤1 include
include Comparable
attr :str
#步骤2 实现<=>方法,下面是通过字符长度来实现<=>
def <=>(other)
str.size <=> other.str.size
end
def initialize(str)
@str = str
end
def inspect
@str
end
end
s1 = SizeMatters.new("Z")
s2 = SizeMatters.new("YY")
s3 = SizeMatters.new("XXX")
s4 = SizeMatters.new("WWWW")
s5 = SizeMatters.new("VVVVV")
s1 < s2 #=> true
s4.between?(s1, s3) #=> false
s4.between?(s3, s5) #=> true
[ s3, s2, s5, s4, s1 ].sort #=> [Z, YY, XXX, WWWW, VVVVV]
<=>操作符比较的是操作数和参数值的ord值,这个ord是ordinal,是字符的第一个字母在ascii中的排序
"a".ord #97
"b".ord #98
"A".ord #65
100.ord #100
#比较第一个字符的ord值,如果第一个ord的值相同,比较第二个
"a" <=> "A" #1
"A" <=> "a" #-1
"aa" <=> "aA" #1
Comparable的方法
#类引入了Comparable并且实现了<=>方法,则该类具备了下面的方法,这些方法都是基于<=>来进行实现的
<
<=
>
>=
==
between?
clamp
#clamp方法说明
12.clamp(0, 100) #=> 12
523.clamp(0, 100) #=> 100
-3.123.clamp(0, 100) #=> 0
'd'.clamp('a', 'f') #=> 'd'
'z'.clamp('a', 'f') #=> 'f'
clamp方法的说明:如果操作数在参数范围内,则返回自身;如果操作数大于参数的最大值,返回参数的最大值;如果操作数小于参数的最小值,返回参数的最小值。
下面讲述effective ruby中关于“<=>”的例子
试着比较“10.10.3”和“10.9.8”两个版本
class Version
attr_reader :major, :minor, :patch
include Comparable
def initialize(version)
@major, @minor, @patch = version.split(".").map(&:to_i)
end
def <=>(other)
return nil unless other.is_a?(Version) #如果是属于不同的对象,则返回nil
[major <=> other.major,
minor <=> other.minor,
patch <=> other.patch].detect{ |n| !n.zero? } || 0
end
end
obj = %w(1.2.0 2.1.3 1.3.5).map { |v| Version.new(v) }
p obj
p obj.sort
因为引入了Comparable,并且实现了<=>方法,那么可以对两个对象进行比较,执行>,>=,<,<=,==等方法
a = Version.new("10.2.8")
b = Version.new("11.3.5")
#可以执行下面的代码
a > b
a < b