Movatterモバイル変換


[0]ホーム

URL:


rochefort's blog

この広告は、90日以上更新していないブログに表示しています。

RubyのComparableモジュールで比較を実装

Effective Ruby

Effective Ruby

項目13 "<=>"とComparableモジュールで比較を実装しよう

例にでてくるのはバージョンの比較を実装する時の話。
例えば、"10.10.3"と"10.9.8"のような比較の場合どうするか?

Object#<=>

2つのオブジェクトが等しいかどうかをテストするだけの汎用メソッド。

classVersionattr_reader(:major,:minor,:patch)definitialize(version)@major,@minor,@patch = version.split(".").map(&:to_i)endend>>%w(10.10.3 10.9.8).map { |v|Version.new(v) }.sortArgumentError (comparison ofVersion withVersion failed)# オブジェクトが等しくなければnilを返す>> v1 =Version.new("10.10.3")>> v2 =Version.new("10.9.8")>> v1 <=> v2=>nil

なので<=>を実装する

classVersionattr_reader(:major,:minor,:patch)definitialize(version)@major,@minor,@patch = version.split(".").map(&:to_i)end# 追加def<=>(other)returnnilunless other.is_a?(Version)# 各桁を比較し0でないものがあればその値を返す。全部0なら0を返す。    [ major <=> other.major,      minor <=> other.minor,      patch <=> other.patch,    ].detect { |n| !n.zero? } ||0endend>>Version.new("10.10.3") <=>"a"=>nil>>Version.new("10.10.3") <=>Version.new("10.11.3")=>-1>>Version.new("10.11.3") <=>Version.new("10.10.3")=>1>>Version.new("10.10.3") <=>Version.new("10.10.3")=>0

ついでに比較演算子

"<", "<=", "==", ">", ">=" はComparableモジュールをincludeすればok。

classVersionincludeComparable# これ追加attr_reader(:major,:minor,:patch)definitialize(version)@major,@minor,@patch = version.split(".").map(&:to_i)enddef<=>(other)returnnilunless other.is_a?(Version)    [ major <=> other.major,      minor <=> other.minor,      patch <=> other.patch,    ].detect { |n| !n.zero? } ||0endend>> v1 =Version.new("10.10.3")>> v2 =Version.new("10.11.3")>> [v1 < v2, v1 <= v2, v1 == v2, v1 >= v2, v1 > v2]=> [true,true,false,false,false]>>Version.new("10.10.10").between?(v1, v2)>=true

覚えておくべき事項

  • オブジェクトの順序は、"<=>演算子を定義し、Comparableモジュールをインクルードして実装しよう
  • "<=>"演算子は、左日演算子が右日演算子と比較できないものならnilを返す。
  • クラスのために"<=>"を実装した場合、特にインスタンスをハッシュキーとして使うつもりなら、eql?を"=="の別名にすることを検討しよう。別名にする場合には、hashメソッドもオーバーライドしなければならない。

最後のやつは、こんな感じに実装すると良い。

classVersion  alias_method(:eql?,:==)defhash    [major, minor, patch].hashendend
About
id:rochefortid:rochefort

Ruby・Rails・Mac・Web・Tech、時々日々のことについて書いています。

follow
Search
Top Entries
はてなブックマーク数
Categories
Comments

    引用をストックしました

    引用するにはまずログインしてください

    引用をストックできませんでした。再度お試しください

    限定公開記事のため引用できません。

    読者です読者をやめる読者になる読者になる

    [8]ページ先頭

    ©2009-2025 Movatter.jp