Feature #5861
String#version_compare
| Status: | Rejected | Start date: | 01/08/2012 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 0% |
||
| Category: | core | |||
| Target version: | 2.0.0 |
Description
バージョン番号っぽい文字列を比較するメソッド、String#version_compare を追加しませんか。
"2.6.18".version_compare("2.6.3") #=> 1
などと使います。
詳細な仕様は Gauche の gauche.version モジュールの version-compare 関数の仕様を丸パクリするのが良いと思います。
提案している名前も Gauche そのままです。
http://practical-scheme.net/gauche/man/gauche-refj_103.html
それなりにユースケースはある…というか今まさにテストを書いていて、
Linux カーネルのバージョン番号を欲しくなったのですが、いかがでしょうか。
History
Updated by kosaki (Motohiro KOSAKI) 5 months ago
> バージョン番号っぽい文字列を比較するメソッド、String#version_compare を追加しませんか。
> "2.6.18".version_compare("2.6.3") #=> 1
> などと使います。
>
> 詳細な仕様は Gauche の gauche.version モジュールの version-compare 関数の仕様を丸パクリするのが良いと思います。
> 提案している名前も Gauche そのままです。
> http://practical-scheme.net/gauche/man/gauche-refj_103.html
>
> それなりにユースケースはある…というか今まさにテストを書いていて、
> Linux カーネルのバージョン番号を欲しくなったのですが、いかがでしょうか。
うーん。正直ぴんときません。まずさきほどなるせさんがコミットされた
r34232ですが、バージョンの比較処理は1行で書けています
> Index: test/socket/test_socket.rb
>===================================================================
>--- test/socket/test_socket.rb (revision 34231)
>+++ test/socket/test_socket.rb (revision 34232)
>@@ -322,6 +322,12 @@
> }
>
> ip_addrs.each {|ai|
>+ if /linux/ =~ RUBY_PLATFORM && ai.ip_address.include?('%') &&
>+ (`uname -r`[/[0-9.]+/].split('.').map(&:to_i) <=> [2,6,18]) <= 0
>+ # Cent OS 5.6 (2.6.18-238.19.1.el5xen) doesn't correctly work
>+ # sendmsg with pktinfo for link-local ipv6 addresses
>+ next
>+ end
それに加えて、(なるせさん自身も指摘されているように)バージョン番号に規則性などないので
意図通り動かないケースが絶対でてきてバグ対応がめんどくさそうです。また、rubyのintreeでは
テストケースぐらいしかユーザがいなさそうなので、それだったら正規表現で適当に誤魔化しても
十分という気がします。
また、Linux固有の話の話として、RHEL6の2.6.32ではバグるけど、Ubuntuの2.6.32ではバグらないとか
xenカーネルでのみトラブルがおきるといった例外はいくらでも思いつき、結局、主要ユースケースが
バグ回避のワークアラウンドのような例外系である限りに置いてなんでもできる正規表現最強はゆるがないんじゃないかという感触でいます。
なにか見落としていたらご指摘よろしくお願いいたします
Updated by nobu (Nobuyoshi Nakada) 5 months ago
Yui NARUSE wrote:
> バージョン番号っぽい文字列を比較するメソッド、String#version_compare を追加しませんか。
> "2.6.18".version_compare("2.6.3") #=> 1
> などと使います。
Gem::Version.new("2.6.18")<=>Gem::Version.new("2.6.3") でいいんじゃないでしょうか。
Updated by naruse (Yui NARUSE) 5 months ago
(2012/01/08 10:30), KOSAKI Motohiro wrote:
> うーん。正直ぴんときません。まずさきほどなるせさんがコミットされた
> r34232ですが、バージョンの比較処理は1行で書けています
>
>> + (`uname -r`[/[0-9.]+/].split('.').map(&:to_i) <=> [2,6,18]) <= 0
この方法がイマイチなのは以下の 2 点ですね。
* split でたくさん String ができる
* バージョン比較という意図がわかりづらい
> それに加えて、(なるせさん自身も指摘されているように)バージョン番号に規則性などないので
> 意図通り動かないケースが絶対でてきてバグ対応がめんどくさそうです。また、rubyのintreeでは
> テストケースぐらいしかユーザがいなさそうなので、それだったら正規表現で適当に誤魔化しても
> 十分という気がします。
指摘しているのはわたしではなく、gauche の仕様を決めた人かマニュアルを書いた人ですね、
たぶん shiro さん?
gauche 側にとっては仕様かどうかの決定は難しい問題ですが、わたしの提案では
「gauche 仕様の丸パクリ」としているので、バグかどうかの判断は明快です。
正規表現だと "2.6.13" <=> "2.6.4" の時に面倒になります。
(ようするに Ruby と違って可変長の場合)
また、OpenSSL のようにアルファベットを使う流儀も悩ましい。
> また、Linux固有の話の話として、RHEL6の2.6.32ではバグるけど、Ubuntuの2.6.32ではバグらないとか
> xenカーネルでのみトラブルがおきるといった例外はいくらでも思いつき、結局、主要ユースケースが
> バグ回避のワークアラウンドのような例外系である限りに置いてなんでもできる正規表現最強はゆるがないんじゃないかという感触でいます。
正規表現だと桁またいだ瞬間一気に複雑化しますからねぇ。
Updated by matz (Yukihiro Matsumoto) 4 months ago
- Status changed from Assigned to Rejected
Stringクラスのメソッドにする必然性はないように思います。バージョン的比較というのはそこまで一般的ではないような。
不満があれば、理由を添えて再オープンしてください。
Matz.