From: Koji Arai Date: 2000-05-14T01:03:47+09:00 Subject: [ruby-dev:9673] Re: IO.popen 新井です。 >>> From: Koji Arai >>> Date: 13 May 2000 23:29:23 +0900 >>> Subject: [ruby-dev:9672] IO.popen > 新井です。 > * io.c (rb_io_s_popen): should check whether has a block. # 余談: この場合は、whether to かな?英語は中学レベルでも難しい(汗) IO.popen()の新しい仕様がよくわからなかったものですから。1.5 向けに最近のIO.popenのマニュアルを書いてみました(以下)、 popen(command [, mode [, proc]]) commandをサブプロセスとして実行し,そのプロセスの標準入出力との間にパイ プラインを確立します.mode はオープンするIOポートのモードを指定するもの で, "r", "r+", "w", "w+", "a", "a+"のいずれかです(省略された時のデフォ ルトは"r"). 生成したパイプ(IOオブジェクト)を返します。ブロックが与えられた場合は生 成したIOオブジェクトを引数にブロックを実行し、その結果を返します。 コマンド名が"-"の時,Rubyはforkを行い,自分自身の分身(子プロセス)とのパ イプラインを生成します.このとき、引数procが指定されていれば、子プロセ スはこれを実行します。procが指定されず、ブロックがあればnilを引数に子プ ロセスはブロックを実行します。(ブロックは親も実行することに注意しなけれ ばなりません) 子プロセスはprocやブロックの実行後に終了*せず*nilを返します。 となっています。なんか複雑ですがあってますかね?(本来私はド キュメント書きがへたくそなんですよ^^;) で、書いてて思ったのですが、新しい引数procは、どうも、 commandが"-"のときだけ意味があるのですね。procの指定を第3引 数でなく第1引数にするってのはどうでしょう? 文字列でprocを指定できませんが、そういう需要はないと勝手に判 断しました(^^; # 採用されれば、前のパッチは捨てて以下。 Sat May 13 15:48:22 2000 Koji Arai * io.c (rb_io_s_popen): use 1st argument instead of 3rd one. * io.c (rb_io_s_popen): should check whether to have a block. Index: io.c =================================================================== RCS file: /home/cvs/ruby/io.c,v retrieving revision 1.28 diff -u -p -u -r1.28 io.c --- io.c 2000/05/12 09:07:41 1.28 +++ io.c 2000/05/13 15:48:22 @@ -1577,8 +1577,9 @@ rb_io_s_popen(argc, argv, self) { char *mode; VALUE pname, pmode, port, proc; + char *cmd; - if (rb_scan_args(argc, argv, "12", &pname, &pmode, &proc) == 1) { + if (rb_scan_args(argc, argv, "11", &pname, &pmode) == 1) { mode = "r"; } else { @@ -1589,15 +1590,27 @@ rb_io_s_popen(argc, argv, self) if (len == 0 || len > 3) rb_raise(rb_eArgError, "illegal access mode"); } - Check_SafeStr(pname); - port = pipe_open(RSTRING(pname)->ptr, mode); + + if (TYPE(pname) == T_STRING) { + Check_SafeStr(pname); + cmd = STR2CSTR(pname); + proc = Qnil; + } + else { + cmd = "-"; + proc = pname; + } + + port = pipe_open(cmd, mode); if (NIL_P(port)) { + /* child */ if (!NIL_P(proc)) { rb_eval_cmd(proc, rb_ary_new2(0)); } - else { - rb_yield(port); + else if (rb_iterator_p()) { + rb_yield(Qnil); } + return Qnil; } else if (rb_iterator_p()) { return rb_ensure(rb_yield, port, rb_io_close, port); -- 新井康司 (Koji Arai)