:pぴー.sendせんど(:pぴー, :pぴー)

mokoaki
mokoriso@gmail.com

2017/07/22

Comparable

Ruby技術者認定試験の書籍写経メモ

何に使われているのか、何に使うのか

自作のクラスに <=> メソッドだけ自力で実装する

class Moko
  attr_reader :id

  def initialize(id)
    @id = id
  end

  def <=>(other)
    id <=> other.id
  end
end

こいつの<=>はつまらないものですが、テスト用なんで許して下さい

Moko.new(5) <=> Moko.new(4)
=> 1

Moko.new(5) <=> Moko.new(5)
=> 0

Moko.new(5) <=> Moko.new(6)
=> -1

もちろん他のメソッドは実装してないから使えません

Moko.new(5) < Moko.new(4)
NoMethodError: undefined method '<'

<=>メソッドだけ自力で実装した自作のクラスに、Comparableモジュールをincludeする

class Moko
  include Comparable
  attr_reader :id

  def initialize(id)
    @id = id
  end

  def <=>(other)
    id <=> other.id
  end
end

完了です。メソッドを確認してみると何かメソッドが増えてます 微妙に増えてます

Moko.methods
:<
:>
:<=
:>=
:between?
:clamp

ぱぱっと説明しちゃいます

Moko.new(3) < Moko.new(6)
=> true

Moko.new(3) > Moko.new(6)
=> false

Moko.new(3) <= Moko.new(6)
=> true

Moko.new(3) >= Moko.new(6)
=> false

数値もComparableをインクルードしているので同様な処理が可能である・・まぁ今まで意識せずに使ってきたんだけど

6 < 3
=> false

6 > 3
=> true

6 <= 3
=> false

6 >= 3
=> true

6 >= 6
=> true

6 <= 6
=> true

Comparable#between?

引数で指定した下限、上限の範囲内であればtrueを返す

Moko.new(3).between?(Moko.new(2), Moko.new(5))
=> true
1.between?(2, 5)
=> false

3.between?(2, 5)
=> true

7.between?(2, 5)
=> false

Comparable#clamp

Moko.new(1).clamp(Moko.new(2), Moko.new(5))
=> #<Moko:0x007fd166836640 @id=2>

Moko.new(3).clamp(Moko.new(2), Moko.new(5))
=> #<Moko:0x007fd1669c6de8 @id=3>

Moko.new(7).clamp(Moko.new(2), Moko.new(5))
=> #<Moko:0x007fd167842660 @id=5>
15.clamp(20, 30)
=> 20

25.clamp(20, 30)
=> 25

35.clamp(20, 30)
=> 30