Project

General

Profile

Bug #11177

DATAでEOF文字以降が読めない

Added by mame (Yusuke Endoh) over 4 years ago. Updated over 4 years ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
ruby -v:
ruby 2.2.2p95 (2015-04-13 revision 50295) [x64-mingw32]
[ruby-dev:48994]

Description

遠藤です。

Windows で __END__ 以降に EOF 文字 (\x1A) があったとき、それより先が読めないのは仕様でしょうか。

gen.rb:

puts "p DATA.read"
puts "__END__"
puts "foo\x1Abar"

以下のように実行すると再現します。

> ruby gen.rb > t.rb
> ruby t.rb
"foo"

DATA.binmode.read などとしてみても同じです。

もちろん、Linux では先まで読めます。Windows でも、ソースコードをパイプで流し込んだ場合はなぜか読めます。

> ruby < t.rb
"foo\x1Abar\n"

さらに、EOF 以降に文字がいっぱいあった場合、EOF 以降の一部の文字が抜け落ちるような挙動になるようです。

gen2.rb:

puts "p DATA.read"
puts "__END__"
puts "foo\x1A" + "X" * 8192 + "Z"

> ruby gen2.rb > t.rb
> ruby t.rb
"fooXXXXXXXXXXXXXXXXXXXXXXXXXXXZ\r\n"

バッファリングのバグっぽい挙動ですが、バグでしょうか。

--
Yusuke Endoh mame@ruby-lang.org

History

Updated by nobu (Nobuyoshi Nakada) over 4 years ago

Yusuke Endoh wrote:

Windows で __END__ 以降に EOF 文字 (\x1A) があったとき、それより先が読めないのは仕様でしょうか。

text modeでそうなるというのは当然仕様でしょう。

DATA.binmode.read などとしてみても同じです。

その時点ではもう読んじゃってますから。

もちろん、Linux では先まで読めます。Windows でも、ソースコードをパイプで流し込んだ場合はなぜか読めます。

\x1AがEOFとみなされるのは、ファイルから読んだときだけです。

さらに、EOF 以降に文字がいっぱいあった場合、EOF 以降の一部の文字が抜け落ちるような挙動になるようです。

gen2.rb:

puts "p DATA.read"
puts "__END__"
puts "foo\x1A" + "X" * 8192 + "Z"

> ruby gen2.rb > t.rb
> ruby t.rb
"fooXXXXXXXXXXXXXXXXXXXXXXXXXXXZ\r\n"

バッファリングのバグっぽい挙動ですが、バグでしょうか。

これはDATAを使わなくとも再現しますね。

$ ./ruby -e 'puts "foo\x1A" + "X" * 8192 + "Z"' > txt
$ ./ruby -e 'open("txt"){|f|p f.gets; p f.read}'
"foo"
"XXXXXZ\n"

Updated by mame (Yusuke Endoh) over 4 years ago

なるほど、メカニズムがよく理解できました。ありがとうございます。

ではその上で質問です。

  1. \x1A の後のバッファがすっ飛ぶのは仕様でしょうか。(DATA に限らず)

  2. 読み込み途中で binmode にすることは非対応でしょうか。
    もし内部バッファにたまっているのが改行コード変換済みだったら
    無理かなあと思いますが。(ソース読んでなくてすみません)

非対応であれば、例外にしてくれると嬉しいなあと思います。
(これは必要なら別途 feature request にします)

--
Yusuke Endoh mame@ruby-lang.org

Also available in: Atom PDF