1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

2つのバージョン番号文字列について「以上」「以下」「より大きい」「より小さい」「同じ」の比較判定をする

Last updated at Posted at 2018-02-17

課題

アプリケーションのバージョン番号について、以上(「以下」「より大きい」「より小さい」「同じ」)を判定したい。

例えば、 1.3.21.2.3 より大きい(一般的には新しい)、1.3.22.3.2 より小さい(一般的には古い)というな判定をしたい。

ふわっとした仕様

バージョニングルールはソフトウェアによって色んなパターンがあるようです。ここではバージョンにあれこれ考えを巡らせてみる - Qiita の「数字によるバージョン」を参考に次の内容で対応することにします。

  • 同じアプリケーションの2つのバージョン番号同士について「以上」「以下」「より大きい」「より小さい」を判定できる
  • バージョン番号は . で区切られた文字列
    • 数字以外の文字列は無視する
  • メジャー・マイナーの2階層、加えてビルドとリビジョンの4階層だけでなく、複数階層パターンに対応する
  • 比較対象のバージョニングルールは階層の数を除いて途中で変更されないこと

バージョン番号の例

  • 1
  • 0.3
  • 0.0.1
  • My Software 0.0.1

シュッと実装

比較メソッドを実装する際に、Ruby の Comaprable モジュールを使います。

Comparable モジュールの比較演算子を定義する事で、通常の数値比較のように直感的なインターフェースになります(テストケースを参照)。

require 'test/unit'

class VersionComparator
  include Comparable

  attr_reader :splited_version

  def initialize(version)
    @splited_version = version.gsub(/[^\d.]+/, '').split('.').map(&:to_i)
  end

  def <=>(other)
    @splited_version <=> other.splited_version
  end
end

class TestVersionComparator < Test::Unit::TestCase
  def test_ufo
    # test <
    assert_equal true, VersionComparator.new('0.0.1') < VersionComparator.new('0.0.2')
    assert_equal false, VersionComparator.new('0.0.5') < VersionComparator.new('0.0.2')
    assert_equal true, VersionComparator.new('0.0.5') < VersionComparator.new('0.1.2')
    assert_equal false, VersionComparator.new('0.0.5') < VersionComparator.new('0.0.5')
    assert_equal false, VersionComparator.new('0.5') < VersionComparator.new('0.0.5')
    assert_equal true, VersionComparator.new('0.0.5') < VersionComparator.new('0.5')
    assert_equal true, VersionComparator.new('My Software 0.0.1') < VersionComparator.new('My Software 0.0.2')

    # test <=
    assert_equal true, VersionComparator.new('0.0.1') <= VersionComparator.new('0.0.2')
    assert_equal false, VersionComparator.new('0.0.5') <= VersionComparator.new('0.0.2')
    assert_equal true, VersionComparator.new('0.0.5') <= VersionComparator.new('0.1.2')
    assert_equal true, VersionComparator.new('0.0.5') <= VersionComparator.new('0.0.5')
    assert_equal false, VersionComparator.new('0.5') <= VersionComparator.new('0.0.5')
    assert_equal true, VersionComparator.new('0.0.5') <= VersionComparator.new('0.5')
    assert_equal true, VersionComparator.new('My Software 0.0.1') <= VersionComparator.new('My Software 0.0.2')

    # test >
    assert_equal false, VersionComparator.new('0.0.1') > VersionComparator.new('0.0.2')
    assert_equal true, VersionComparator.new('0.0.5') > VersionComparator.new('0.0.2')
    assert_equal false, VersionComparator.new('0.0.5') > VersionComparator.new('0.1.2')
    assert_equal false, VersionComparator.new('0.0.5') > VersionComparator.new('0.0.5')
    assert_equal true, VersionComparator.new('0.5') > VersionComparator.new('0.0.5')
    assert_equal false, VersionComparator.new('0.0.5') > VersionComparator.new('0.5')
    assert_equal false, VersionComparator.new('My Software 0.0.1') > VersionComparator.new('My Software 0.0.2')

    # test >=
    assert_equal false, VersionComparator.new('0.0.1') >= VersionComparator.new('0.0.2')
    assert_equal true, VersionComparator.new('0.0.5') >= VersionComparator.new('0.0.2')
    assert_equal false, VersionComparator.new('0.0.5') >= VersionComparator.new('0.1.2')
    assert_equal true, VersionComparator.new('0.0.5') >= VersionComparator.new('0.0.5')
    assert_equal true, VersionComparator.new('0.5') >= VersionComparator.new('0.0.5')
    assert_equal false, VersionComparator.new('0.0.5') >= VersionComparator.new('0.5')
    assert_equal false, VersionComparator.new('My Software 0.0.1') >= VersionComparator.new('My Software 0.0.2')

    # test ==
    assert_equal true, VersionComparator.new('0.0.1') == VersionComparator.new('0.0.1')
    assert_equal true, VersionComparator.new('My Software 0.0.2') == VersionComparator.new('My Software 0.0.2')
  end
end
1
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?