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

results matching ""

    No results matching ""