[#44725] Set[Set[1]]==Set[Set[1]] は偽? — "5.5" <5.5@...>

5.5 です。

22 messages 2008/03/04

[#44782] $stdin.rewind が exec した子プロセスに伝わらない? — SATOH Fumiyasu <fumiyas@...>

さとうふみやす @ OSS テクノロジです。

11 messages 2008/03/17
[#44783] Re: $stdin.rewind が exec した子プロセスに伝わらない? — Kazuhiro NISHIYAMA <zn@...> 2008/03/17

西山和広です。

[ruby-list:44719] Re: パイプ経由コマンド実行?

From: Yukihiro Matsumoto <matz@...>
Date: 2008-03-03 07:29:49 UTC
List: ruby-list #44719
まつもと ゆきひろです

In message "Re: [ruby-list:44718] Re: パイプ経由コマンド実行?"
    on Mon, 3 Mar 2008 15:52:34 +0900, "M. Morita" <m-morita@ybrain.co.jp> writes:

|I/O の open(fnm,"w").write は完結した処理だと思っていたのですが、
|実装は違っているようですね。
|
|  % ruby
|  open("foo","w").write("a\n")
|  open("foo","w").write("b\n")

まず、openによって作られたファイルへの書き込みは内部のバッファ
に格納されます。それが実際に書き込まれるのは

  * 改行があった
  * バッファがいっぱいになった
  * 明示的にflushした
  * closeした

ときです。バッファリングするのは性能上の理由です。毎回書き込
みをするとプログラムのIO性能が低下するからです。

上のプログラムでは最初の行でopenしていますが、一度writeしたあ
と放置されていますので、IOオブジェクトは今後書き込みがあるか
もしれないので、バッファをflushしません。openの戻り値を他で参
照していないので、人間は「もう終わった」と思うかもしれません
が、それはRubyの関知するところではないからです。

そのまま2行目で同じファイルをopenしています。これも同様に
writeされた結果はバッファに格納されたままです。

で、このプログラムは実際にはcloseを行うことなくこのまま終了し
てしまうのですが、さすがに書き込んだはずのデータがflushも
closeもされていないという理由でプログラム終了と共にバッファご
と消滅してはまずいので、プログラム終了時にバッファの内容を書
き込みます。その順番は不定です。

この場合、同じファイルに対してふたつIOをopenしていますので、
お手元ではたまたま最初にopenしたIOが 後に flushしたので二番
目の書き込みが生き残った形になります。

|で結果は foo は "b" が書き込まれると持っていたのですが
|
|  % cat foo
|  a
|
|なのですね。最初の I/O をひきずってしまうのですね。
|思っていた程、単純でないようです。

どのように思っていらっしゃったかは知る由もないのですが、はっ
きり言えることは「なんらかの方法でちゃんとcloseしてください」
です。

                                まつもと ゆきひろ /:|)

In This Thread