From: Wakou Aoyama Date: 1999-07-21T22:58:07+09:00 Subject: [ruby-dev:7394] Re: Ruby 1.3.5 青山です。 Wed, Jul 21, 1999 at 05:57:28PM +0900 において Yukihiro Matsumoto さん曰く: > まず第1にストリームポインタが末尾にあるとき、これを > > * EOFとみなす > * EOFとみなさない > > という点があります。原さんは「みなさない」方が単純で良いので > はないかということですね。私はこちらにはあまりこだわりはあり > ませんが、「みなす」方がstdioの設計になじむようには思います。 以前の IO#eof? や feof(3) のどちらもストリームポインタではなく、次の読 み込みに成功するかどうかで判定しているようですし、これは、末尾の判定が ファイル以外ではそのようにしか判定できないからだと思われます。 この事から、ファイル以外も扱う IO クラスの機能としては、ストリームポイ ンタによる EOF の判定は行うべきではなく、それが末尾と思われる位置(?)に あっても、やはり EOF とはみなさない方が良いのではないかと思われます。 というか、単純に feof(3) でそのまま IO#eof? を実装するとそうなるようだ というだけなのですが。 > 次にストリームポインタが末尾にある(たとえば空ファイルの先頭) > ときにread(),read(n)がなにを返すかということを考えましょう。 > 選択肢は > > * 空文字列("") > * nil > * 一度目は空文字列、2度目以降はnil feof(3) の利用により、状況が少しかわったと思います。前述のように、 feof(3) はストリームポインタの位置とは無関係に EOF を判定しています。 そして、[ruby-dev:7388] のように、ファイルサイズが 0 の場合でも、 長さが 0 より大きな read(n) を行うまでは EOF を返しません。 すなわち、feof(3) の挙動にしたがった場合、EOF に達したら nil という条 件のままで、ファイルサイズが 0 の場合であっても、read(), read(0), read(n) いずれも最初はかならず文字列を返すという事になります。 さらに、EOF を返すのは、2度目という基準ではなく、0 よりも大きな長さの read(n) を行った後となっています。read(0) は何度行っても EOF の判定に 影響しません。これは、 read(0) はファイルポインタを動かさないとみなし ているのでしょう。 かつ、feof(3) は EOF に達したかどうかのフラグを持っているので、一度 EOF に達したとみなされると、以降はずっと EOF と判定するようです。しか し、これも長さが動的にかわる場合がありえる事から、clearerr(3) で、その フラグを戻せるようです。(IO#clearerr も必要?) という事で、ちょっとややこしい話になってしまいましたが、こんな感じですね。 $ /usr/src/ruby/ruby -e 'io = open("0"); p io.stat.size p io.eof? p io.read(1) p io.eof? p io.read(1) ' 0 false "" true nil $ /usr/src/ruby/ruby -e 'io = open("0"); p io.stat.size p io.eof? p io.read(1) p io.eof? p io.read(0) ' 0 false "" true nil $ /usr/src/ruby/ruby -e 'io = open("0"); p io.stat.size p io.eof? p io.read(0) p io.eof? p io.read(0) ' 0 false "" false "" $ /usr/src/ruby/ruby -e 'io = open("0"); p io.stat.size p io.eof? p io.read(0) p io.eof? p io.read(1) p io.eof? ' 0 false "" false "" true 後は、現在の read() は read(0) と同様に次の EOF 判定に栄養を与えないよ うなので、これを影響を与えるようにすると、長さを無限大とした read(n) の挙動になります。 ----- 結局、IO#eof? を feof(3) で実装するなら、read の EOF で nil という動き はそのままに、EOF の判定を feof(3) にまかせては? というだけの案なの ですが、長くなりましたね... -- 青山 和光 Wakou Aoyama