From: Shin-ichiro Hara Date: 1999-07-22T18:04:50+09:00 Subject: [ruby-dev:7395] Re: Ruby 1.3.5 原です。 |Wed, Jul 21, 1999 at 05:57:28PM +0900 において |Yukihiro Matsumoto さん曰く: | |> まず第1にストリームポインタが末尾にあるとき、これを |> |> * EOFとみなす |> * EOFとみなさない |> |> という点があります。原さんは「みなさない」方が単純で良いので |> はないかということですね。私はこちらにはあまりこだわりはあり |> ませんが、「みなす」方がstdioの設計になじむようには思います。 あれ?私は常に「みなす」方を推していたんですが、、、 でも、"eof(3)" の挙動を考えてとちょっと考え直しました。(^^; In message "[ruby-dev:7394] Re: Ruby 1.3.5" on 99/07/21, Wakou Aoyama writes: | |青山です。 |この事から、ファイル以外も扱う IO クラスの機能としては、ストリームポイ |ンタによる EOF の判定は行うべきではなく、それが末尾と思われる位置(?)に |あっても、やはり EOF とはみなさない方が良いのではないかと思われます。 これに賛成!(^^;; と、いうか EOF に達しているけど、eof? は false であることを許す、といったらいいのかな。(つまり必ずしも eof? は EOF にポインタが来ていることを表さない。)EOF という言葉が いろんな意味で使われてごちゃごちゃになってますね、、、 すなわち、eof? は 直前の1バイト以上の読み込みで読み込み終了になった場合 ture、 そうでないとき false。 直前に1バイト以上の読み込みをしてない場合は不定(か true)。 みたいに正式に定義してしまうのが良い、と思うようになりました。 したがって、いきなり iof? は良くない: while !io.eof? s.concat io.read(1024) end というコードはあまり勧められない。正しいのは loop do s.concat io.read(1024) break if io.eof? end である。と、いうことになりますか。つまり、 |そして、[ruby-dev:7388] のように、ファイルサイズが 0 の場合でも、 |長さが 0 より大きな read(n) を行うまでは EOF を返しません。 と、いうことです。 |さらに、EOF を返すのは、2度目という基準ではなく、0 よりも大きな長さの |read(n) を行った後となっています。read(0) は何度行っても EOF の判定に |影響しません。これは、 read(0) はファイルポインタを動かさないとみなし |ているのでしょう。 これも同意します。Ruby でも read(0) は eof? に対しても全く影響を 与えないことにしたらいいと思います。 さて、read(0) の返り値についてですが、私は io.read(0) は io の状態にかかわらず常に nil を返す を提案します。これは私の最初の提案なんだけど、理由はちょっと変わって "read(2)" では read(,,0) の返り値は 0 としている からです。 これでいえば、0バイトファイルは read(0) は nil だけど eof? は false なわけです。(どちらを何回やっても。) さらにこの際、「"read(2)" が 0 を返す場合は Ruby の read(n) も 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(1) |' |0 |false "" #=> nil |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 "" #=> nil |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 "" #=> nil |false "" #=> 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(1) |p io.eof? |' |0 |false "" #=> nil |false "" #=> nil |true 一方、残る問題 read() ですが、0バイトファイルに read() を2回 したとき、 (1) "", "" (2) "", nil のどっちにするかですね。つまり (1a) read() は read(n) と全く違うものと思う (2a) read() は read(n) と類似と思う の違いです。私は (1a) を推しています。0バイトファイルに対して 1回目の read() が "" であるのに read(0) は nil なので、read() と read(n) が類似とはいえないから、というのが一つの論拠です。