もりきゅうです。

matz / ruby-lang.org (Yukihiro Matsumoto) wrote:
> これで最後のpreviewにしたいです。残っている問題があればどん
> どん報告してください。$stdinまわりをいじったのでfcgiとか確認
> してくださると助かります。

ええと、CVS版での報告でかまいませんか。
$def{out,err} は obsolete ですか?
$stdin に設定するオブジェクトに必要な条件がよくわかんないです。

で、何を報告すべきか混乱してきたので ^^;
わかりやすい $stdout と対比させてみます。
$stdout に設定するオブジェクトに必要なのは write メソッドです。
ここで大事なのは print や puts はこの write メソッドを呼び出して
くれることです:

D:\tmp>type stdout1.rb
class RubyIO
  def initialize
    @f = open("tmp.txt","r+")
  rescue Errno::ENOENT
    @f = open("tmp.txt","w+")
  end
  def write(s)
    @f.write s
  end
end
io = RubyIO.new
$stdout = io
puts("hi")
print("hi")
puts("hi")

D:\tmp>ruby -vd stdout1.rb
ruby 1.8.0 (2003-07-28) [i386-mswin32]

D:\tmp>type tmp.txt
hi
hihi

今回 $stdin の扱いは $stdout とちょっと似てます。
$stdout に設定するオブジェクトに必要なのは read メソッドです(getcではなく)。
ここで悲惨なのは getc や gets はこの read メソッドを呼び出して
くれないことです:

D:\tmp>type stdin1.rb
class RubyIO
  def initialize
    @f = open("tmp.txt","r+")
  rescue Errno::ENOENT
    @f = open("tmp.txt","w+")
  end
  def read # 引数はどうするんかな
    @f.read
  end
  def gets
    @f.gets
  end
end
io = RubyIO.new
$stdin = io
getc
while gets
  print
end

D:\tmp>ruby -vd stdin1.rb
ruby 1.8.0 (2003-07-28) [i386-mswin32]
stdin1.rb:16: warning: getc is obsolete; use STDIN.getc instead

ここで私の環境では悲惨なことに
ruby.exe というダイアログが開き
----
問題が発生したため、ruby.exe を終了します。ご不便をおかけして申し訳ありませ
ん。

作業途中であった場合、その情報は失われた可能性があります。

この問題を Microsoft に報告してください。
弊社に送信するためのエラー報告が作成されました。弊社では、この報告を...
...
[デバッグ]    [エラー報告を送信する(S)][送信しない(C)]
----
まあ、このバグには目をつむり、見なかったことにしてですね…

知りたいのは、$stdinに設定するオブジェクトの必要十分条件。
今のところ
* IOからの継承は必要ない
* readメソッドを定義する
* getsを呼び出すときはgetsメソッドが必要
こういう条件になっているように思います。
ではほかに必要なメソッドは何か? ということが気になります。

# 寝ぼけてるかも…

----
YOSHIDA Kazuhiro  moriq / moriq.com  http://www.moriq.com/