いわおかです。

In the message <4319124A.1040000 / kyoto-wu.ac.jp>,
  on Sat, Sep 03, 2005 at 12:03:20PM +0900, Hideo Konami wrote:
> 小波です。
> 
> デフォルトの gets と STDIN.gets というのは同じ動作をするものだと
> 思っていたのですが,次のようなコードで試してみると,gets のみで
> は(私にとっては)不可解な現象が起きます。

gets では Kernel#gets が、STDIN.gets では IO#gets が呼ばれていると
いうことでは?

% refe Kernel\#gets
Kernel#gets
--- gets([rs])
--- readline([rs])

    Ruby インタプリタ実行時に引数として与えられたファイル(なければ標準
    入力)をつなげた仮想的なファイル(組み込み変数 $<
    や ARGF でアクセスできる) から一行読み込んで、文字列を返しま
    す。ファイルの終りに到達した時には nil を返します。

    行の区切りは引数 rs で指定した文字列になります。rs の
    デフォルト値は組み込み変数 $/ の値です。読み込
    んだ文字列は組み込み変数 $_ にもセットされます。

    rs に nil を指定すると行区切りなしとみなしてファイルの内容を
    すべて読み込みます。
    空文字列 "" を指定すると連続する改行を行の区切りとみなします
    (パラグラフモード)。

    readline は gets と同じ働きをしますが、
    ファイルの最後まで読むと例外 EOFError を発生させます。

% refe IO\#gets
IO#gets
--- gets([rs])

    一行読み込んで、読み込みに成功した時にはその文字列を返します。
    ファイルの終りに到達した時には nil を返します。
    IO#each [IO/each] と同じように動作します
    が、こちらは 1 行返すだけで繰り返しません。

    行の区切りは引数 rs で指定した文字列になります。rs の
    デフォルト値は組み込み変数 $/ の値です。

    rs に nil を指定すると行区切りなしとみなします。
    空文字列 "" を指定すると連続する改行を行の区切りとみなします
    (パラグラフモード)。

    IO#gets はgets 同様、読み込んだ文字列を変数
    $_ にセットします。

> ・上書きされるべきファイルが存在しないときには,同然そのまま書き
>  込みが行われます。
> ・既にファイルがあると,gets で入力待ちせずに進んでしまい,しか
>  も str には前回の実行時に fo.puts でバッファに書き込んだはず
>  の文字列が代入されたままになっていることが分ります。

「バッファに書き込んだはずの文字列が代入されたままになっている」の
ではなく、書き込んだファイルから読み込んでいるのでしょう。

いわおか