From: KOSAKI Motohiro Date: 2010-02-15T13:25:56+09:00 Subject: [ruby-dev:40417] Re: [Bug #2516] IO#reopen Compatibility (original: ) > 2010年2月11日15:24 Yusuke Endoh : > > チケット #2516 が更新されました。 (by Yusuke Endoh) > > > > > > 遠藤です。 > > > > IO#reopen について調べているのですが、さっぱりわかりません。 > > > > > >  $ cat foo.txt > >  1 > >  2 > >  3 > > > >  # 1.8: 途中位置の File に reopen したら読み込めない > >  f1, f2 = File.new("foo.txt"), File.new("foo.txt") > >  f2.gets > >  f1.reopen(f2) > >  p f1.gets #=> nil > >  p f1.gets #=> nil > >  p f1.gets #=> nil > >  p f1.pos  #=> 2 > > > >  # 1.9: reopen した後は get 早い者勝ち? pos の結果が違う > >  f1, f2 = File.new("foo.txt"), File.new("foo.txt") > >  f1.reopen(f2) > >  p f1.gets #=> "1\n" > >  p f2.gets #=> nil > >  p f1.pos  #=> 2 > >  p f2.pos  #=> 2 > > > >  f1, f2 = File.new("foo.txt"), File.new("foo.txt") > >  f1.reopen(f2) > >  p f2.gets #=> "1\n" > >  p f1.gets #=> nil > >  p f1.pos  #=> 6 > >  p f2.pos  #=> 2 > > > > > > reopen の想定ユースケースってどんなんでしょうか。 > > dup2 のようなものかと思っていたのですが、そんな挙動でもないですよね。 > > ユースケース次第では、reopen の引数に渡された IO は close してしまう > > 方が混乱しなくてすむと思います。 > > > > # できればユースケースの議論の前に挙動が変わった理由を把握したかった > > # のですが、何がバグで何が仕様かわかりませんでした。 > > Linuxだと同等の以下のCプログラムが > > #include > > int main(void) > { > FILE *f1, *f2; > char buf[80]; > > f1 = fopen("inputfile", "r+"); > printf("%s", fgets(buf, 80, f1)); > f2 = freopen("inputfile", "r+", f1); > > printf("%s", fgets(buf, 80, f1)); > printf("%s", fgets(buf, 80, f1)); > printf("%s", fgets(buf, 80, f1)); > > printf("pos %d\n", ftell(f1)); > printf("pos %d\n", ftell(f2)); > > } > > こうなります。 > > 1 > 1 > 2 > 3 > pos 6 > pos 6 > > 内部的には struct FILEが struct _IO_marker をポイントしていて、 _IO_markerは共有、そっちでpos管理している。 反応がないので、誰も興味がないのだと判断します。遠藤さんとIRCで調整のうえ kosakiがボールを握ることにしました。 現状 io.dup もposが狂った動きをしているので一緒に直すことになると思います。 # たぶん、月末のTokyo Ruby KaigiのハンズオンでHello Worldとか # 教えてもらいながら、内職ハックする事になりそう。