質問: rubygems ないし bundler で利用される gem のバージョンの仕様はどうなっていますか? 1. あるバージョン文字列が与えられたときに、それらの大小はどのように決定されていますか? とくに、以下のようなコーナーケースの挙動が知りたいと思っています。 * 1.0.0 vs 1.0.0.0 * 1.0.0 vs 1.0.0-beta * 1.0.0 vs 1.0.0.beta 2. それをふまえて、 Gemfile における `~> V.V` (ないし `~> V.V.V`) はどのような動作をしますか? ### 背景 gem においては --pre でダウンロードされる、 betaN バージョンを bundler で指定したいと思いました。bundler の github issue によると、 ``` gem "eventmachine", ">= 1.0.0.beta" ``` のように記述すればよいと書いてあります。 この指定が、ちょっときもちわるいと思い、正しい挙動を理解しておかないと、後々ハマりそうだな、と思ったので、質問しています。
回答: Gem::Version#<=>のソースを見ると、以下のロジックで比較しているようです。 * バージョン文字列を数字の並びまたはアルファベット小文字の並びで分解(たとえば`'1.0.0-beta1'`なら`[1, 0, 0, 'beta', 1]`) * 両配列の先頭から1要素ずつループ + 配列が終わっていれば数値の`0`が入っているとみなす(たとえば`[1, 'beta']`と`[1, 'beta', 1]`を比較するときは、前者を`[1, 'beta', 0]`相当に) + 同じ位置の値が同じであれば次の要素へ + 数値と文字列なら数値のほうが大きいとして終了 + 数値と数値、または文字列と文字列なら、その値で比較して終了