From: Urabe Shyouhei Date: 2009-04-05T07:18:52+09:00 Subject: [ruby-dev:38275] Re: big time Tanaka Akira さんは書きました: > In article <49D5FA02.6090809@ruby-lang.org>, > Urabe Shyouhei writes: > >> なるほど。検査メソッドという表現から述語メソッドを想像していましたが、例外を発 >> 生するメソッドであればありかもしれないと思います。 > > あとからもうひとつの可能性を考えつきました。 > > もしかして、卜部さんが想定する TypeError というのは、 > File.utime が発生するものだったりしませんか? > > File.utime が発生する例外については、サブクラスを作らなくて > も「時刻が time_t の範囲外である」というメッセージで例外を発 > 生するのは簡単だし、そうすべきだと思います。 > >> 利点がないんでしょうか。ライブラリ作者が責任範囲を明確にできるのは利点ではない >> ですかね。それがアプリケーション開発者の不幸に繋がるかは分かりませんが。 > > どう明確になるんでしょう? > > File.utime に渡す時刻を引数に指定するのがアプリケーションの > 責任なら、それはそれで明確ではないですか? > > それに失敗したら time_t の範囲外という例外が出るわけですし。 ここまでまとめて返答しますが、想定しているのはFileUtils.touchのような、 File.utimeへのラッパーライブラリです。FileUtils.touchはFile.utimeが受け付けない ような引数は受け付けたくないわけです。ところが、田中さんのパッチを当てると /usr/lib/ruby/1.9.2/fileutils.rb:1033:in `utime': time out of system range (ArgumentError) from /usr/lib/ruby/1.9.2/fileutils.rb:1033:in `block in touch' from /usr/lib/ruby/1.9.2/fileutils.rb:1030:in `each' from /usr/lib/ruby/1.9.2/fileutils.rb:1030:in `touch' from -e:1 などというエラーが出ますね?これでは知らない人が見ればFileUtilsにバグがあるよう に見えるわけです。FileUtilsの側としては、FileUtilsは悪くないわけですから、この ようなバックトレースを表示せずに、なるならもっと手前のところで例外になってほし い。つまり、この例で言えば -e:1:in `new': time out of range (ArgumentError) from -e:1 とかそんな感じになってほしいわけです。 >> utimeの直後にfstatで確認するとか。いやもちろん競合状態でうまくいかないのは理解 >> できますので、難しそうかなとは思いますが。 > > GNU/Linux で VFAT なファイルシステムを mount して > あるファイルを 1970-01-01 に File.utime すると、失敗しないし、 > stat すると設定できたように見えるんだけど、マウントし直すと > 1980-01-01 になっているという現象を見つけてしまいました。 > > stat しても実際になにが起きているのかはわからないようです。 それは私の理解とは違いますね。fstatが成功して意図した値が返ってくるなら、それは 更新に成功しています。その後の値が保証されないのは、たとえば他のユーザーが横か らtouchしたり、いくらでも弄ることは可能なことからも明かです。そもそもVFATじゃな くてもumountした時点で、ディスク抜いて他のマシンでmountして更新時刻弄ってるかも しれないじゃないですか。 utimeはあくまで設定した瞬間以降の値は保証していないはずと思います。 >> [ruby-dev:38202] のケースを救いたいです。 > > 読み直してみました。 > > touch クローンであれば、コマンドライン引数解釈器が生成した > Time オブジェクトがそのまま File.utime までたどりつくでしょ > うから、File.utime が「time_t の範囲外である」というメッセー > ジで失敗すれば、Time オブジェクトを生成した、touch クローン > の作者が問題を見つけるのは別に難しくないのではないでしょうか。 > > ライブラリ側からから見ると、アプリケーションから渡された > Time オブジェクトをそのまま File.utime に渡している限り、そ > のエラーメッセージは外部の問題であることを明らかに示している > のでその旨を述べてバグレポートを却下すればいいのではないでしょ > うか。 バグレポートが何回も何回も来ることを考えてください。 ライブラリの作者は一人のことが多いですが、ユーザーは普通、一人より多いです。何 回却下しても同じバグが次々と別の人から報告されることはあります。「自分のせい じゃないバグ報告でモチベーションが削がれ」とは、そういう状況を指しています。 >>> その解決による利点は、互換性を損なうことを含む欠点よりも大き >>> なものですか? >> 前から理解できないので言及してこなかったわけですが、その大きさってのはどうやっ >> て定量的に評価するんですか?大きさを比較するには量的な評価ができないことには不可 >> 能だと思います。 > File.utime が Time オブジェクトを受け付けなくなると、 > いままで File.utime に Time を渡していたすべてのコードで問題 > が起きます。 > > それに対して、File.utime が、time_t の範囲外の Time オブジェ > クトを受け付けないというのは、すべてよりは少ないコードでしか > 問題が起きないでしょう。 この推測には私は賛成も反対もできません。 過去、Timeがtime_tの範囲を外れたことがないので、そのようなケースが多いか少ない かは予測不可能だと思います。 特にTime.nowが2038年に近づくとそのようなケースは増えるのではないかと個人的には 危惧しています。 > 卜部さんが救いたいというのは後者に関する話ですが、それは前者 > の問題よりは少ないでしょう。 したがって定量的評価はこの部分にこそ欲しかったのですが。 > また、File.utime がなんらかの範囲外でうまく動かないという意 > 味で、似た問題は 64bit time_t で NFSv3 とか GNU/Linux で > VFAT とか既にあるので、そこからの類推も可能です。ML の過去の > メールを検索しても範囲外の問題と明確にわかるものはありません > でした。これから類推すると問題は例外的な話におさまるでしょう。 Rubyの場合、time_tの範囲外のTimeオブジェクトはこれまで生成できなかったので、ML を検索しても問題が報告されていないのは自明と思います。 > あと、前から、ということなので、Time を拡大する利点と > それによる File.utime に対する欠点の比較についても触れておき > ます。 > > 利点のほうが大きいと私が考えるのは、Time を使うケースと > File.utime を使うケースで前者がずっと多いという経験から来て > います。 > > このことは、Google Code Seach で検索すると > * lang:ruby Time が約230,000件 > * lang:ruby File.utime が 924件 > という数になることからも裏付けられます。Time 検索結果がすべ > て Time クラスを指しているわけではないでしょうが、これだけの > 差があれば、Time クラスがずいぶんと多いのは確かでしょう。 > (実際、検索結果を眺めると、1/100 よりはずいぶんと大きな割合 > で Time クラスを使うコードがヒットしています) > > 従って、ある変更によって、File.utime に使うときの欠点とそれ > 以外での利点が両方あった場合、実際に使う回数を考えると、利点 > のほうがずっと多くなることが推測できます。 そうですか。Timeを使うケースが多いのは分かりました。