うえの@ぶるーすかいです。

これって実装の都合上仕方ないんでしょうか。
使っている Ruby のバージョンは 1.4.5 です。

buf = STDIN.read
p buf              # => "foo"
r,w = IO.pipe
STDIN.reopen r
r.close
Thread.new {
  w.write buf
  w.close
}
p STDIN.eof?       # => true ????
p STDIN.read       # => nil ????

最初の行で STDIN を dup すれば回避はできるのですが…

# ちなみに、やろうとしているのは標準入力の先読み表示です。
# CGI スクリプトのデバッグとかに使えるかな、と思って。


あと、write と*引数無しの* read ではスレッドが切り替わらないようで、
buf がパイプのバッファより大きくなるとフリーズします。

write でスレッドを切り替えない理由は何となく分かりますが、
read のほうは対処しておいたほうが良いのでは?

STDOUT.sync = true
buf = STDIN.read
r,w = IO.pipe
Thread.new {
  n = 0
  print "write\n"
  buf.each_byte { |c|
    select nil, [w]
    w.putc c
    n += 1
    print "wrote #{n} bytes\r"
  }
  print "\nend write\n"
  w.close
}
print "\nread\n"
s = r.read       # <= サイズを指定していないとフリーズ
print "\n", s.inspect, "\n"


とりあえず ad hoc な patch をば。


--- ruby-1.4.5/io.c.orig	Thu Jul 13 14:27:50 2000
+++ ruby-1.4.5/io.c	Thu Jul 13 17:49:29 2000
@@ -422,10 +422,15 @@
     }
     str = rb_str_new(0, siz);
     for (;;) {
+#if 0
 	READ_CHECK(fptr->f);
 	TRAP_BEG;
 	n = fread(RSTRING(str)->ptr+bytes, 1, siz-bytes, fptr->f);
 	TRAP_END;
+#else
+	static size_t io_fread(char *, size_t, FILE *);
+	n = io_fread(RSTRING(str)->ptr+bytes, siz-bytes, fptr->f);
+#endif
 	if (n == 0 && bytes == 0) {
 	    if (feof(fptr->f)) return Qnil;
 	    rb_sys_fail(fptr->path);



-=====--===-
   うえの かつひろ @ BLUE-SKYNET    <unnie / blue.sky.or.jp>  --=
---=----===-                    http://www.blue.sky.or.jp/  -==