この広告は、90日以上更新していないブログに表示しています。
例にでてくるのはバージョンの比較を実装する時の話。
例えば、"10.10.3"と"10.9.8"のような比較の場合どうするか?
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
最後のやつは、こんな感じに実装すると良い。
classVersion alias_method(:eql?,:==)defhash [major, minor, patch].hashendend
引用をストックしました
引用するにはまずログインしてください
引用をストックできませんでした。再度お試しください
限定公開記事のため引用できません。